프론트엔드/React

[React] useEffect()

진기명기 2023. 4. 25. 11:13
🫠 리액트를 배우면서 가장 많이 사용하는 Hook은 useState()와 useEffect()인 것 같다. 
API를 받아오거나, 화면을 시작하는 등의 액션을 위해 useEffect를 사용하여 기본적인 세팅을 하고 있다.
useEffect의 특징과 사용해야 하는지, 어떨 때 사용해야 하는지를 정리하고자 한다.

 

 


💜 useEffeect()란?

> 컴포넌트가 렌더링 된 후, React에게 어떤 일을 수행해야 하는지 명령하는 역할

> useEffect()는 명령을 기억한 후, DOM 업데이트가 수행되면 해당 명령을 불러옴

> useEffect()는 렌더링 이후, 모든 업데이트에서 실행

 

 

 

💜 useEffect() 예시

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

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

  useEffect(() => {
    console.log(count);
  }, [count]);
}
💡 useEffect()를 사용하는 방법을 설명하기 위해 간단한 예시 형식을 가져왔다. 

✅ useEffect를 사용할 때, 위에 예시처럼 [count]로 지정할 경우, count의 값이 업데이트될 때마다 useEffect가 실행된다.
따라서 count의 상태값이 변경됨에 따라 새로운 화면을 렌더링 해야한다든지, 새로운 API를 불러와야 한다든지 상황에 맞게 사용하면 좋다. 
✅ 빈 배열 [ ]로 놓을 경우, 처음 화면이 렌더링 될 때만 useEffect가 실행되어, useEffect 구문 안에 작성한 코드가 한 번만 실행된다. 

❗️ 말로만 설명할 경우, 정확한 이해가 되지 않을 수 있으니 상태값을 계속해서 업데이트 해야하는 상황을 예시로 들어 아래와 같이 설명해 보겠다. 

 

 

 

💜 현재 시각 나타내기

⏱ 현재 시간을 초단위로 나타내는 화면을 구현해보자

💡 시간을 나타내는 상태값 필요 
💡 시간을 초 단위로 업데이트해주는 함수 필요
import React, { useState, useEffect } from "react";

const FunctionClock = () => {
  const [date, setDate] = useState(new Date());

  function tick() {
    setDate(new Date());
  }

  ...

  return (
    <div style={{ textAlign: 'center' }}>
      <h1>현재 시간은?</h1>
      <h2>It is {date.toLocaleTimeString()}.</h2>
    </div>
  );
}

export default FunctionClock
✅ 상태값 date가 시간에 따라 계속적으로 업데이트되는 화면을 구현하고자 한다. 

❗️ setDate(new Date())을 해줘서 시간이 업데이트될 것 같지만, 아래와 같은 화면을 볼 수 있다. 

 

 

 

❗️ 실행한 시각으로 화면에 나오지만, 시간이 흘러도 고정된 시간으로 화면에 표시된다. 

 

 

 


💜 useEffect()를 사용해 보자

  // Class에서 componentDidMount의 역할
  useEffect(() => {
    console.log('componentDidMount');
    const timerId = setInterval(tick, 1000)

    return () => {
      console.log('componentWillUnmount');
      clearInterval(timerId);
    };
  }, []);
✅ setInterval을 통해 1초마다 tick 함수가 실행되도록 하고, 이를 useEffect() 구문에 넣어 화면이 렌더링 될 때, 실행되도록 하였다. 
✅ 아래 영상 결과를 보면 화면이 실행되자마자 componentDidMount --> componentWillUnmount가 바로 출력된 것을 확인할 수 있다.

💜 상태값 변경될 때마다 콘솔창에 출력해 보자

  // Class에서 componentDidUpdate의 역할
  useEffect(() => {
    console.log('componentDidUpdate');
    console.log(date);
  }, [date]);
✅ 또 다른 useEffect()를 사용하여 date의 값이 1초마다 업데이트될 때, 이를 캐치하여 콘솔창에 찍어보려 한다. 
💡 [date]로 작성하여 date의 값이 변경될 때마다 실행되는 것을 확인하자!

 

 

 

💜 전체 코드

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

const FunctionClock = () => {
  const [date, setDate] = useState(new Date());

  function tick() {
    setDate(new Date());
  }

  // Class에서 componentDidMount의 역할
  useEffect(() => {
    console.log('componentDidMount');
    const timerId = setInterval(tick, 1000)

    return () => {
      console.log('componentWillUnmount');
      clearInterval(timerId);
    };
  }, []);

  // Class에서 componentDidUpdate의 역할
  useEffect(() => {
    console.log('componentDidUpdate');
    console.log(date);
  }, [date]);

  return (
    <div style={{ textAlign: 'center' }}>
      <h1>현재 시간은?</h1>
      <h2>It is {date.toLocaleTimeString()}.</h2>
    </div>
  );
}

export default FunctionClock
✅ class를 사용할 때는 useEffect()의 역할이 componentDidMount - componentDidUpdate - componentWillUnmount와 같기 때문에, 표시해 둔 것이니 참고!

 

 

 

참고자료 : https://ko.legacy.reactjs.org/docs/hooks-effect.html