프내기

[React]useEffect 제대로 알고 쓰자 본문

React

[React]useEffect 제대로 알고 쓰자

봄나물소년 2023. 12. 7. 19:56

useEffect

useEffect(setup, dependencies?)

 

컴포넌트가 렌더링될 때 어떤 일(side effect)을 실행할 수 있도록 하는 hook.

 

여기서 말하는 Side effect란 화면이 렌더링된 이후에 비동기로 처리되어야 하는 부수적인 효과들을 말한다.  외부 api를 가져오는 일이 이에 해당한다. 어떤 데이터를 가져오기 위해 일단 화면에 렌더링 할 수 있는 것들을 먼저 렌더링하고 실제 데이터는 비동기로 가져오는 것이 권장된다. 요청 즉시 1차 렌더링을 함으로써 api요청이 늦어지건 실패했을 때 영향을 최소화 시킬 수 있기 때문에 사용자 경험 면에서 좋다.

Side Effect에는 두가지 종류가 있다.

  1. 정리(clean-up) 필요한 것(컴포넌트가 삭제(unmount)되었을 때)
  2. 정리가 필요하지 않은것 (network request, DOM 수동 조작, 로깅 ..)

useEffect의 쓰임은 다음과 같다.

  • 렌더링 때마다
  • 최초 렌더링 시에만
  • 특정 값이 변할 때
  • cleanup 함수 사용

먼저 useEffect 내부 로직이 어떻게 컴포넌트의 마운트가 된 뒤에 실행된다건 이런 것이다.

import { useEffect } from "react"

export default function Test() {
  console.log('test1111 component');
  useEffect(() => {
    console.log('test1111 useeffect');
  }, [])
  return (
    <div>
      <h1>test1111</h1>
      <Test2/>
    </div>
  )
};

function Test2() {
  console.log('test2222 component');
  useEffect(() => {
    console.log('test2222 useeffect');
  }, [])
  return (
    <>
    <h1>test2222</h1>
    <Test3/>
    </>
  )
};

function Test3() {
  console.log('test3333 component');
  useEffect(() => {
    console.log('test3333 useeffect');
  }, [])
  return (
    <h1>test3333</h1>
  )
};

최상단 부모컴포넌트인 Test1이 자식컴포넌트 Test2와 Test2의 자식컴포넌트로 Test3을 담고있는 모습이다.

각 컴포넌트의 내부와 useEffect 내부에 콘솔을 하나씩 찍어주었다.

콘솔에는 이렇게 나온다.

최하단의 자식 컴포넌트까지 컴포넌트들이 마운트된 후 아래에서 위로 useEffect 내부 로직이 실행됨을 알 수 있다. 

그럼 이제 useEffect의 쓰임을 하나씩 보자.

 

렌더링 때마다

dependency에 아무것도 넣어주지 않는다.

useEffect(() => {
 // 컴포넌트가 렌더링 될 때마다 실행된다 
})

최초 렌더링 시에만

dependency에 빈배열을 넣는다.

useEffect(() => {
 // 컴포넌트가 최초 렌더링 될 때만 실행된다 
}, [])

특정 값이 변할 때

dependency에 setup에서 쓰는 props, state, 컴포넌트 내부에 직접 선언된 모든 변수와 함수를 넣는다.

그럼 이 값들에 변화가 일어날 때마다 useEffect의 setup function이 재실행된다.

const [count, setCount] = useState(0);

 useEffect(() => {
   console.log('useEffect count: ', count);
   // count값이 변할 때만 실행된다
 }, [count])

cleanup 함수 사용

import { useEffect, useState } from "react"

export default function Test() {
  const [count, setCount] = useState(0);
  const countUp = () => setCount(count + 1);
  const [name, setName] = useState("GodDaeHee");
  const handleChangeName = (e) => setName(e.target.value);

  useEffect(() => {
    console.log('useEffect', count);
    return () => {
      console.log('clean up', count);
    }
  }, [count])
  return (
    <div>
      <input onChange={handleChangeName} />
      <p>{count}번 클릭!</p>
      <button onClick={countUp}>Click Me</button>
    </div>
  )
}

setup에 return 값을 넣어준다.

return에는 state의 값이 들어간다.

위 콘솔을 보면 최초에 useEffect가 실행되어 count에 0이 할당된다.

처음 버튼을 클릭하면 이전의 count값을 받아 clean up 함수가 먼저 실행된 후 다음 useEffect가 재실행됨을 알 수 있다.

두 번째 역시 마찬가지로 clean up 함수가 먼저 실행되면서 이전 count값인 1을 받았고 그 다음 useEffect가 재실행되어 count2를 가져왔다.

위에서 컴포넌트가 unmount 될 때 cleanup 함수를 쓴다고 설명했다.

unmount 되는 상황은 useEffect를 담고있는 컴포넌트가 DOM에서 사라지는 상황를 말한다.

게시물이 삭제되는 상황 같은 것을 예로 들 수 있겠다.

이때 return 안에는 이전에 삭제 버튼을 누르며 어딘가에 등록된 이벤트를 삭제해주어
그렇지 않았을 때 계속해서 쌓이는 이벤트에 의해 메모리 누수가 되지않도록 도움을 준다.

끝.

 

참고

https://goddaehee.tistory.com/308

 

[React] 7. React hooks[2] - useEffect란?

7. React hooks[2] - useEffect란? 안녕하세요. 갓대희 입니다. 이번 포스팅은 [ React hook 중 useEffect에 대한 내용 ] 입니다. : ) https://ko.reactjs.org/docs/hooks-effect.html 1. useEffect 훅이란? - 컴포넌트가 렌더링 될

goddaehee.tistory.com

https://velog.io/@yes3427/React-Side-Effect

 

[React] Side Effect란?

React 컴포넌트가 화면에 렌더링된 이후에 비동기로 처리되어야 하는 부수적인 효과들을 Side Effect라고 한다. 대표적인 예로어떤 데이터를 가져오기 위해서 외부 API를 호출하는 경우,일단 화면에

velog.io

 

'React' 카테고리의 다른 글

[React]useMemo와 useCallback의 차이(+ React.memo)  (0) 2024.01.16