현인

[React Hooks] useEffect 사용법 본문

기술 학습/React

[React Hooks] useEffect 사용법

현인(Hyeon In) 2023. 8. 30. 14:19
※ 제 글은 리액트를 처음 접하시거나 아직 Hook에 대해 익숙하지 않으신 분들이 빠르게 Hook에 대해 이해하실 수 있도록 핵심만 정리했습니다. 조금 더 상세한 내용은 React Hook 공식 문서를 통해서 이해하시면 좋을 것 같습니다.

참고 자료 : 김민준. 『리액트를 다루는 기술』. 길벗, 2019.

useEffect

useEffect는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook입니다. 클래스형 컴포넌트의 componentDidMount와 componentDidUpdate를 합친 형태로 보아도 무방합니다.

useEffect 적용 예시

useState 글에서 만들었던 Info 컴포넌트에 useEffect를 한 번 적용해 보겠습니다.

import React, { useEffect, useState } from 'react'

const Info = () => {
  const [name, setName] = useState('');
  const [nickname, setNickname] = useState('');

  useEffect(() => {
    console.log('렌더링이 완료되었습니다!');
    console.log({
      name,
      nickname
    });
  });

  const handleChangeName = e => {
    setName(e.target.value);
  };

  const handleChangeNickname = e => {
    setNickname(e.target.value);
  }

  return (
    <div>
      <div>
        <input type="text" value={name} onChange={handleChangeName} />
        <input type="text" value={nickname} onChange={handleChangeNickname} />
      </div>
      <div>
        <div>
          이름: {name}
        </div>
        <div>
          닉네임: {nickname}
        </div>
      </div>
    </div>
  )
}

export default Info

이전 useState 글에서 말씀드렸다시피 state가 변경되면 리렌더링이 일어납니다.

useEffect를 활용하여 렌더링 될 때마다, 콘솔에 name 값과 nickname 값을 출력하는 작업을 설정해두었기에 위와 같은 결과물이 나오게 됩니다.

useEffect가 두 번 실행되는 것 같아요!

위 예제에서도 컴포넌트가 처음 나타났을 때 ‘렌더링이 완료되었습니다!’ 라는 문구가 두 번 출력이 되었는데요. 이는 React.StrictMode가 적용된 개발 환경에서만 발생하는 현상이며 useEffect를 사용한 코드에 문제가 있는지 감지하기 위하여 두 번 실행이 된다고 합니다.
React.StrictMode를 적용한 적이 없으시다구요?

아마 CRA(create react app)으로 리액트 프로젝트를 만드셨다면, index.js 파일에 <React.StrictMode> 태그로 컴포넌트가 감싸진 것을 확인하실 수 있을 겁니다. 해당 태그를 지우면 React.StrictMode 가 해제되긴 하지만 굳이 해제하실 필요는 없습니다!

컴포넌트가 마운트될 때만 실행하고 싶을 때

useEffect에서 설정한 함수를 컴포넌트가 화면에 처음으로 렌더링될 때만 실행하고, 업데이트될 때는 실행하지 않으려면 useEffect 훅의 두 번째 파라미터로 비어있는 배열을 넣어 주면 됩니다.

위 예제에서 useEffect Hook을 다음과 같이 변경해보겠습니다.

useEffect(() => {
  console.log('마운트 될 때만 실행됩니다!');
}, []);

보이시는 것처럼 처음으로 컴포넌트가 렌더링될 때만 useEffect의 작업이 수행되고 state가 변경되어도 useEffect의 작업은 수행되지 않습니다.


특정 값이 업데이트될 때만 실행하고 싶을 때

useEffect를 사용할 때, 특정 값이 변경될 때만 호출하고 싶은 경우도 있겠죠. useEffect의 두 번째 파라미터로 전달되는 배열 안에 검사하고 싶은 값을 넣어 주면 됩니다. 배열 안에는 useState를 통해 관리하고 있는 상태를 넣어 주어도 되고, props로 전달 받은 값을 넣어 주어도 됩니다.

위 예제의 useEffect Hook을 다음과 같이 변경해보겠습니다.

useEffect(() => {
  console.log(name);
}, [name]);

name 값이 변경될 때 마다 콘솔에 name 값이 출력되고 nickname 값이 변해도 아무런 반응이 없는 것을 확인하실 수 있습니다.

대부분의 경우, useEffect를 사용할 때는 이렇게 두 번째 파라미터 배열에 의존하는 값을 넣어줍니다. 빈 배열이나 의존 값이 들어있는 배열을 넣는 경우는 있어도, 배열을 아예 생략하는 상황은 거의 없다고 생각하면 됩니다.


뒷정리하기

컴포넌트가 언마운트되기 전이나 업데이트되기 직전에 어떠한 작업을 수행하고 싶다면 useEffect에서 뒷정리(cleanup) 함수를 반환해 주어야 합니다.

위 예제의 useEffect Hook을 다음과 같이 변경해보겠습니다.

useEffect(() => {
  console.log('effect 호출');
  console.log('업데이트 이후 name 값: ' + name);
  console.log('-------------렌더링-------------');
  return () => {
    console.log('cleanup 호출');
    console.log('업데이트 이전 name 값: '+ name);
  }
}, [name]);

렌더링될 때마다 뒷정리 함수가 계속 나타나는 것을 확인할 수 있습니다. 그리고 뒷정리 함수가 호출 될 때는 업데이트되기 직전의 값을 보여줍니다.

오직 언마운트될 때만 뒷정리 함수를 호출하고 싶다면 다음과 같이 useEffect 함수의 두 번째 파라미터에 비어 있는 배열을 넣으면 됩니다.

useEffect(() => {
  console.log('effect');
  return () => {
    console.log('unmount');
  }
}, []);

 

반응형

'기술 학습 > React' 카테고리의 다른 글

[React Hooks] useState 사용법  (0) 2023.08.30