본문 바로가기

프로그래밍&IT/React & CSS

[Fast Campus , React] 9. React Hooks, functional 컴포넌트 사용하기

React Hooks?

ReactConf 2018에서 발표된, class 없이 state를 사용할 수 있는 새로운 기능.

class component로 사용되어온 react에서 느껴온 불편함을 해결하기 위해 개발.

React Hooks는 Functional Component를 사용함.

class / functional 컴포넌트 차이

함수형 컴포넌트에선 어떤 기능을 못 쓰는가?

리액트 생명주기

중요한 생명주기를 함수형 컴포넌트에선 사용을 못 했다.

→ 이것은 React 16.8 Hooks 업데이트로 변경됨

이로 인해 함수형 컴포넌트도 생명주기를 사용할 수 있기에 데이터를 가져오고, 컴포넌트 시작하자 API호출 등 많은 부분을 할 수 있게 되었다.

리액트 생명주기 사용 비

컴포넌트에서 생명주기를 사용하는 부분

  • class component에서 사용하던, componentDidMount, ComponentDidUpdate, componentWillUnmount를 각각 구현해서 처리해 주지만,
  • 리액트 훅을 사용할 땐, useEffect안에서 모두 처리가 가능하다.

* HOC 컴포넌트를 custom react hooks로 대체해서 많은 wrapper 컴포넌트를 줄인다.

HOC (Higher Order Component)?

화면에서 재사용 가능한 로직만을 분리해서 component로 만들고, 재사용 불가능한 UI와 같은 다른 부분들은 parameter로 받아서 처리하는 방법.

 위의 A, B 페이지가 유저 리스트를 가져오는 같은 부분이 있는데, 이 중복이 되는 부분을 따로 HOC컴포넌트로 만든다.

유저 리스트를 가져오는 공통부분은 HOC컴포넌트에 넣어주고 그 HOC컴포넌트로 각각의 컴포넌트로 감싸주면 모든 컴포넌트에 따로 인증을 위한 부분은 넣어주지 않아도 된다.

이 문제는 많은 wrapper컴포넌트가 생길 수 있다는 것.

아래처럼 데이터 흐름을 파악하기가 힘들어진다.

Custom React Hooks를 이용해 해결할 수 있다.

hooks에서 state를 업데이트해 주려면,

const [name, setName] = useState("");

setName을 이용해서 state를 업데이트할 수 있다. (name을 업데이트하는 setName함수?)

 

class 컴포넌트 → function 컴포넌트로 바꾸기

  • render() 없이 바로 return
  • state를 useState hook를 이용해서 표현
  • state를 새로운 값으로 update 할 때는, setState("")
  • 마지막에 export default 이름으로 처리 - export default Board

Board.js

import React, { useState } from "react";
import Square from "./Square";
import "./Board.css"

const Board = () => {
    const [squares, setSquares] = useState(Array(9).fill(null));
    const handleClick = (i) => {
        const newSquares = squares.slice(); // slice로 통째 복사
        newSquares[i] = 'X';
        setSquares(newSquares);
    }
    const renderSquare = (i) => {
        return <Square
            value={squares[i]}
            onClick={() => handleClick(i)} />
    }
    return (
        <div>
            <div className="status">Next Player: X</div>
            <div className="board-row">
                {renderSquare(0)}
                {renderSquare(1)}
                {renderSquare(2)}
            </div>
            <div className="board-row">
                {renderSquare(3)}
                {renderSquare(4)}
                {renderSquare(5)}
            </div>
            <div className="board-row">
                {renderSquare(6)}
                {renderSquare(7)}
                {renderSquare(8)}
            </div>
        </div>
    )
}
export default Board

Square.js

import React from 'react'
import "./Square.css"
const Square = ({value, onClick}) => {
  return (
    <button className='square'
        onClick={onClick}>
        {value}
    </button>
  )
}
export default Square