All Articles

Hook2

이전 글에서는 Hook이 왜 세상에 나오게 됬는지에 대한 글이었다.
이 글에서는 Hook의 기능에 대해 작성하고자 한다.

Hook은 class 안에서 사용할 수 없다.
함수형 컴포넌트에서 상태 관련 로직(state, lifecycle 등)을 사용할 수 있게 해주는 역할을 하는 녀석일 뿐이다.
Hook은 useState, useEffect, useCallback 등 네이밍이 use로 시작한다.

useState

class Example extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name = '',
        };
    }

    const onClick = () => {
        this.setState({
            name: 'seong ho',
        })
    }
}

위 코드는 class 컴포넌트, 함수형 컴포넌트로 변환하고 Hook을 사용하면 아래와 같다.

const Example = () => {
  const [name, setName] = useState(초기값);

  onClick = () => {
    setName("seong ho");
  };
};

Hook 중에 useState는 위 처럼 사용한다.
위 변수는 일반 변수와는 달리 state 변수이다.
일반 변수(지역 변수)는 함수가 끝나면 사라지지만 state 변수는 react에 의해 사라지지 않는다.
그런데 왜 변수 선언을 [name, setName] 이런식으로 했을까??
그전에 useState() 라는 녀석을 알아야 한다.
useState() 녀석은 state 변수와 state 변수를 갱신할 수 있는 함수를 반환한다.
따라서 이 2개의 반환 값을 할당하기 위해 배열 구조 분해라는 자바스크립트의 문법을 사용한 것.

var fruitStateVariable = useState("banana"); // 두 개의 아이템이 있는 쌍을 반환
var fruit = fruitStateVariable[0]; // 첫 번째 아이템
var setFruit = fruitStateVariable[1]; // 두 번째 아이템

배열 구조 분해 문법을 사용하지 않으면 이런식으로 …

또한 여러 개의 state 변수를 선언할 수 있다.

useEffect

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {}

  componentDidUpdate() {}
}

위 코드는 class 컴포넌트, 함수형 컴포넌트로 변환하고 Hook을 사용하면 아래와 같다.

const Example = () => {
  const [count, setCount] = useState();

  useEffect(() => {});
};

클래스형 컴포넌트에서 lifecycle 메서드들 중에 componentDidMount, componentDidUpdate, componentWillUnmount를 useEffect Hook으로..

클래스형 컴포넌트에서는 같은 기능 단위의 로직이더라도 lifecycle에 따라 나뉘어지고, 다른 기능 단위의 로직인데 같은 lifecycle에서 섞여 사용되기도 하는 등 함수형 컴포넌트에서 Hook을 사용하면 lifecycle에 따라 나누지 않고 같은 기능
단위의 로직끼리 묶어 분할할 수 있다.

컴포넌트 안에서 useEffect도 여러 번 사용할 수 있다.

componentWillUnmount로 종료할 기능이 있다면 useEffect에서 return해주면된다.
(return에 componentWillUnmount에 작성할 코드를 작성)
useEffect에 두번째 인자로 빈 배열을 주거나, 아무거도 주지 않는다면 딱 componentDidMount처럼 동작
useEffect에 두번째 인자로(무조건 array로) set해서 변경되는 state 변수를 주면 componentDidMount, componentDidUpdate처럼 동작

Hook은 두 가지의 절대적인 규칙이 있다.

  1. 반복문, 조건문 혹은 중첩된 함수 내에서 Hook을 호출하지 마세요.
    => 필요하다면 Hook 안에서 조건문 사용.
    => Hook은 항상 react 함수 내의 최상위 레벨에서 호출해야 합니다.
    => 이 규칙을 따르면 컴포넌트가 렌더링 될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장됩니다.
    => 이러한 규칙은 react가 useState와 useEffect가 여러 번 호출되는 중에도 Hook의 상태를 올바르게 유지할 수 있도록 해줍니다.
  2. react 함수 내에서 Hook을 호출해야 합니다.
    =>일반적인 javascript 함수에서 호출하지 마세요.
    =>react 함수 컴포넌트에서 Hook을 호출하세요.

위 규칙들을 강제하는 eslint-plugin-react-hooks라는 ESLint 플러그인을 출시했습니다.