[React] useEffect 알아보기

Cottonmycotton·2022년 2월 9일
1

React

목록 보기
13/14
post-custom-banner

1. useEffect?

useEffect는 리액트 훅의 하나로 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 해준다. 여기서 렌더링이란 state와 props를 기반으로 UI를 그려내는 행위이다.

형태:
useEffect(함수, 타이밍)

  • 함수: 렌더링이 끝난 후 실행시킬 로직
  • 타이밍: effect를 일으킬 타이밍

1-2. Side Effect

  • 부작용 또는 부수효과라고 불린다.
  • 컴퓨터 용어에서 side effect는 함수의 결과값 이외에 결과에 영향을 미치지 않는 모든것을 말한다. 함수 외부의 상태를 변경하는 것이 side effect이다.
    • 대표적인 예시로 타이머, 데이터 가져오기, DOM에 직접 접근하기, 구독설정하기 등이 side effect이다.
  • 특별한 이유가 없다면 side effect들은 useEffect에서 관리하는 것이 좋다.
    • 렌더링을 하는 과정에서 side effect들은 결과를 도출해내는 과정에 방해가 되면 안된다.
    • 렌더랑과 무관한 로직이 매 렌더링마다 실행되는 것은 전체적으로 봤을때 성능 자체에 악영향을 줄 수있다.

1-3. useEffect가 발생되는 시점

useEffect는 렌더링 이후에 side effect를 실행시킨다. side effect가 렌더링에 영향을 주지 않음을 의미함. 위 형태에서 보았듯이 effect를 일으킬 시점은 두 번째 인자인 의존성 배열에 넘겨주는 값을 통해 실행된다. 즉, 두 번째 인자에 어떤 값이 위치하는 지에 따라 실행되는 시점이 정해진다. 하나씩 살펴보자.

2. useEffect, 언제 일어나는 걸까?

2-2. 컴포넌트가 마운트(첫 렌더링)됐을 때: 빈 배열

  • 컴포넌트가 렌더링 된 후 useEffect 첫 번째 인자로 넘겨준 함수가 실행된다.
  • re-render가 일어났을 때 다시 두 번째 인자에 들어있는 값을 체크한 다음 빈 배열일 경우에는 아무일도 일어나지 않는다.
useEffect(() => {
  console.log('마운트 됐을 때만')
}, []);

2-3. 컴포넌트가 렌더링 될 때마다: 배열을 생략

  • 두 번째 인자 값을 생략했을 때는 re-render가 될 때마다 useEffect가 실행된다.
useEffect(() => {
  console.log('렌더링이 될 때마다')
});

2-4. 특정값이 업데이트 될 때: 해당 값을 넣어준다

  • 배열에 특정값을 넣어주면 그 특정값이 업데이트 될 때 첫 번째 인자로 넘겨준 함수가 실행된다.
useEffect(() => {
  console.log('value가 업데이트 될 때')
}, [value]);

3. Clean up Effect

클린업 이팩트란 이전에 일으켰던 effect를 정리해줄 때 사용한다. 실행시점은 위에서 본 바와 마찬가지이며 useEffect안에 클린업 이팩트를 일으킬 수 있도록 로직을 작성해주면 된다.

useEffect(() => {
  setNum(count);
   return () => {
     setNum(count);
   }
}, []);

아래 로직을 콘솔로 찍어 출력해보았을 때 실행 순서는 다음과 같다.

  • 마운트 됐을때: render -> effect
  • 클릭이벤트가 발생해서 re-render됐을때: render -> clean -> effect

다음 effect가 일어나기 전에 clean up Effect가 발생하는 것을 알 수있다.

function App() {
  const [click, setClick] = useState(false);
  
  console.log('render');
  
  useEffect(() => {
    console.log('effect');
    return () => {
      console.log('clean');
    });
  }, [click]);
  
  return <div onClick={() => setClick(true)}>click me!</div>;
}

참고자료:
https://react.codepot.kr/docs/week05/doc5/

profile
투명인간
post-custom-banner

0개의 댓글