React 공부/기초

Hooks의 개념과 useState(), useEffect()

책다니엘 2024. 1. 14. 07:24
hook이란?

hook은 리액트 16.8에서 새롭게 도입된 개념이다. 기존의  클래스형 컴포넌트에서는 "생명주기 메소드(lifecycle method)"를 사용할 수 있었다. 이를 hook을 이용해 클래스형 컴포넌트보다 간결한 함수형 컴포넌트에서도 사용할 수 있게 되었다.

 

* 생명주기 메소드(lifecycle method)란?

생명주기 메서드는 컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메서드들이다. 추가적으로 컴포넌트에서 에러가 났을 때 호출되는 메서드도 있다.

 

출처: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

 

componentDidMount : 컴포넌트가 처음 나타났을 때
componentDidUpdate : 컴포넌트가 바뀔 때(특정 props가 바뀔 때)
componentWillUnmount : 컴포넌트가 사라질 때

 

이렇게 간단한 개념만 정리하고 넘어간다.

 

hook이란 단어는 프로그래밍에서 원래 존재하는 기능에 '갈고리를 거는 것처럼' 끼어들어가 같이 수행되는 것을 의미한다. 리액트에서의 hook은 클래스형 컴포넌트처럼 리액트에 state관련 함수, lifecycle 관련 함수, 최적화 관련 함수 등 생명주기 기능의 갈고리를 걸어 원하는 시점에 정해진 함수를 실행하도록 만들어진 것이다. 

 

hook 관련된 함수는 모두 use를 사용한다.

 

 

useState()란?

이름에서 알 수 있듯 state를 사용하는 hook으로, 함수 컴포넌트에서는 기본적으로 state를 제공하지 않기 때문에 useState()를 사용해줘야 한다.

 

import React, { useState } from "react";

function Counter(props) {
  const count = 0;

  return (
    <div>
      <p>총 {count}번 클릭했습니다.</p>
      <button onClick={() => count++}>클릭</button>
    </div>
  );
}

export default Counter;

 

Counter 컴포넌트는 클릭을 할 때마다 count변수를 1씩 증가시키는 단순한 컴포넌트이다. 그런데 count를 함수의 변수로 선언해서 사용하게 되면, 버튼 클릭 시 카운트 변수를 업데이트해줘야 하는데, 함수 컴포넌트에는 state를 통한 재렌더링 기능이 없어 새로운 count값이 표시되지 않는다. 이 때 useState()훅을 사용해 함수 컴포넌트에 재렌더링 기능을 제공해준다.

 

useState()는 다음과 같은 방식으로 선언된다.

const [변수명, set함수명] = useState(초기값);

 

이렇게 초기값을 넣어 useState를 노출하면 return값으로 배열이 나온다. return된 배열에는 두가지가 있는데,

1. state로 선언된 변수

2. 해당 state의 set함수이다.

 

useState를 사용하여 함수를 다시 쓰면

import React, { useState } from "react";

function Counter(props) {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>총 {count}번 클릭했습니다.</p>
      <button onClick={() => setCount(count + 1)}>클릭</button>
    </div>
  );
}

export default Counter;

 

이렇게 count변수의 값을 state로 관리할 수 있게 된다. 이 과정은 클래스 컴포넌트에서 setState 함수를 호출해서 state가 업데이트되는 과정과 동일하다.

 

다만, 클래스 컴포넌트에서는 setState()를 통해 모든 state를 변경할 수 있으나, 함수 컴포넌트에서는 변수 각각에 set함수가 따로 존재한다는 것을 기억할 것!

 

 

useEffect()란?


- 컴포넌트가 "렌더링될 때" 특정 작업을 실행시킬 수 있게 하는 Hook

- 리액트의 useEffect() 훅을 사용하면 함수 컴포넌트에서도 side effect를 사용할 수 있게 됨!

* side effect는 일반적으로 '부작용', '부정적인 결과' 등으로 사용된다. 그러나 리액트에서 side effect는 단순히 "효과, 영향"의 뜻으로 사용됨!

이러한 작업을 effect라고 부르는 이유는, 이 작업들이 다른 컴포넌트에 영향을 미칠 수 있으며, 렌더링 중에는 작업이 완료될 수 없기 때문이다. 

- useEffect()는 클래스 컴포넌트에서 제공하는 생명주기 함수인 componentDidMount, componentWillUpdate의 기능을 하나로 통합하여 제공해준다.

 

 

 

2. 사용방법?

 

- 첫 번째 인자(effect)는 함수, 두 번째 인자는 의존성 배열(deps)이 들어간다.

- 의존성 배열은 말 그대로 이 함수가 의존하고 있는 배열, deps 안의 변수 중 하나라도 변경되면 useEffect()가 실행

- 만약 이펙트 함수가 mount, unmount시에 단 한 번만 실행되게 하고 싶으면 이 deps 안에 값을 넣지 않아 빈 배열로 만들어준다.

import react, { useEffect } from "react";
useEffect(effect, [, deps]); // 한 번만 실행하고 싶을 경우(useEffect(effect, [ ]);

 

- useEffect는 렌더링 이후 실행할 함수로, 리액트는 이 함수를 기억했다가 DOM 업데이트 후 불러낸다.

- useEffect()에서 return을 사용할 경우 return 이후의 함수는 컴포넌트가 unmount될 때 실행된다.

 

예시 코드)

import React, { useState, useEffect } from "react";

function Counter(props) {
  const [count, setCount] = useState(0);

  // componentDidMount, componentDidUpdate와 비슷하게 작동합니다.
  useEffect(() => {
    // 브라우저 API를 사용해서 document의 title을 update합니다.
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>총 {count}번 클릭했습니다.</p>
      <button onClick={() => setCount(count + 1)}>클릭</button>
    </div>
  );
}

export default Counter;

 

위 코드처럼 의존성 배열 없이 useEffect를 사용하면 리액트는 DOM이 변경된 이후에 해당 이펙트 함수를 실행하라는 의미로 받아들인다. 

 

그래서 처음 페이지가 렌더링될 때를 포함해 매번 렌더링될 때마다 이펙트 함수가 실행된다. 결과적으로 클래스 컴포넌트의 componentDidMount, componentDidUpdate와 같은 기능을 수행하게 되는 것이다.

 

또한 useEffect()는 함수 안에서 실행되기 때문에 함수의 props와 state에 접근할 수도 있다. 

 

* useEffect 함수 내에서 return을 사용하면 componentWillUnmount와 동일한 역할을 수행한다.

* useEffect Hook은 하나의 컴포넌트 안에 여러 개를 사용할 수 있다.

 

 

지금까지 배운 내용을 정리하면,

useEffect( ( ) => {
    // 컴포넌트가 마운트된 이후,
    // 의존성 배열에 있는 변수들 중 하나라도 변경되었을 때 실행됨
    // 의존성 배열에 빈 배열([ ])을 넣으면 마운트와 언마운트시에 단 한 번만 실행됨
    // 의존성 배열 생략 시 컴포넌트 업데이트시마다 실행됨 

    return ( ) => {
        // 컴포넌트가 마운트 해제되기 전에 실행
}
}, [의존성 변수1, 의존성 변수2, 의존성 변수3, ...])

 

 

출처: 소플, 처음 만난 리액트

'React 공부 > 기초' 카테고리의 다른 글

React, Next.js 주요 개념  (6) 2024.10.03
Hook의 규칙과 custom Hook 만들기  (0) 2024.01.17
useMemo(), useCallback(), useRef()에 대하여  (1) 2024.01.16