[React] useEffect

재웅·2023년 5월 23일
0

오늘의 정리

목록 보기
42/52
post-thumbnail

sideEffect

프로그래밍에서 side effect 란 함수가 함수 내부의 값 외에 외부의 값을 읽어오거나, 수정하는 행위를 의미한다. side effect는 함수의 동작 결과를 예측하기 어렵게 만들기에 일반적으로는 기피해야 하는 대상이지만 side effect를 하나도 발생시키지 않고 프로그래밍을 할 수는 없기 때문에 useEffect hook을 사용하는것이다.프론트엔드 개발에서도 마찬가지로 side effect를 발생시켜야 하는 순간이 있다. 가장 흔한 사례로는 Data Fetching, DOM 접근 및 조작, 구독 등의 행위가 있다.


useEffect

  • React에서 Side Effect의 올바른 발생 시점
const App = () => {
  const doSideEffect = () => {
    // do some side effect
  };

  doSideEffect();

  return <h1>Hello World</h1>;
};

위와 같이 side effect를 발생시키게 되면 두 가지 문제가 발생한다.
1. side effect가 렌더링을 blocking
2. 매 렌더링마다 side effect가 수행

이 두가지 문제점을 해결하기 위해 useEffect를 사용하면 된다.

  • useEffect 사용법
useEffect(콜백 함수);
import { useEffect } from 'react';

const App = () => {
  // 코드 생략

  useEffect(doSideEffect);

  return <h1>Hello, Wecoder</h1>;
};

side effect를 발생시키는 함수를 바로 호출하는 것이 아니라 useEffect의 인자로 전달한다. 위와 같이 useEffect의 인자로 전달된 콜백 함수는 곧바로 호출되는 것이 아니라 모든 렌더링이 완료된 후에 호출된다. 즉 렌더링을 blocking 하지 않고 side effect를 발생시킬 수 있게 되는 것이다.

  • 조건부로 Side Effect 발생시키기
useEffect(콜백 함수, 의존성 배열);
  1. 의존성 배열이 전달되지 않았다면 매 렌더링마다 콜백 함수를 호출한다.
  2. 의존성 배열이 전달되었다면 의존성 배열의 값을 검사한다.
    a. 의존성 배열에 있는 값 중 하나라도 이전 렌더링과 비교했을 때 달라졌다면 콜백 함수를 호출한다.
    b. 의존성 배열에 있는 값이 이전 렌더링과 비교했을 때 모두 다 같다면 콜백 함수를 호출하지 않는다.

예시

import { useEffect } from 'react'

// 사용법
useEffect(콜백 함수, 의존성 배열);

// 1. 의존성 배열이 전달되지 않았으므로 매 렌더링마다 side effect가 실행된다
useEffect(() => {
  // side effect
});

// 2. 첫 번째 렌더링 이후에 side effect를 실행하고
// 그 이후에는 value 값이 변했을 때만 실행한다.
useEffect(() => {
  // side effect
}, [value]);

// 3. 첫 번째 렌더링 이후에 side effect를 실행하고
// 그 이후에는 value1, value2 중 하나라도 변하면 side effect를 실행한다.
useEffect(() => {
  // side effect
}, [value1, value2]);

  • Clean Up Effect
useEffect(() => {
  const countTime = () => {
    console.log('100ms가 지났습니다.');
  };

  setInterval(countTime, 100);
}, []);

side effect는 setInterval 함수를 이용해서 100ms마다 countTime 함수가 호출되도록 하고 있다. useEffect의 의존성 배열에 빈 배열이 전달되었으므로 첫 번째 렌더링 이후에 side effect가 실행된다. 그런데 이 side effect를 clean up 해주지 않는다면 컴포넌트가 unmount 되는 경우 등 setInterval을 통한 구독이 필요 없어진 상황에서도 계속해서 콘솔이 출력되고 있을 것이다. 이를 해결하기 위해서 clean up effect를 사용한다.

useEffect(() => {
  const countTime = () => {
    console.log('100ms가 지났습니다.');
  };

  let clear = setInterval(countTime, 100);
  
  return () => {
   clearTimeout(clear);}
}, []);

useEffect는 clean up 함수를 두가지 경우에 호출해준다.

  1. 다음 side effect를 발생시키기 전
  2. 컴포넌트가 unmount 될 때
profile
오늘의 정리

0개의 댓글