React Hooks - useEffect()

RumbleBi·2022년 7월 15일
0

React

목록 보기
5/9
post-thumbnail

useEffect 란?

함수형 컴포넌트에서 사용하는 Hook 으로 화면에 첫 렌더링이 일어났을 때, 업데이트 되었을 때, 화면에서 사라질 때, 총 3가지 상황에서 사용할 수 있는 Hook이다. 이는 React 클래스형 컴포넌트의 lifecycle(Mount - Update - Unmount)과 비슷하다.

useEffect 의 구성요소

import React, { useEffect } from 'react' 

useEffect(()=> {}, [])

첫 번째 인자로는 콜백함수가 들어가며 이 안에 원하는 코드를 작성해서 동작시킬 수 있다.

두 번째 인자로는 배열을 받는데, 의존성배열이라고 부른다. 배열이 없다면 렌더링 될 때마다 useEffect는 호출이 되고, 빈 배열이라면 최초 첫 렌더링이 일어났을 때만 호출된다. 그리고 배열안에 값을 넣게 된다면 그 값이 업데이트 될 때만 호출되는 방식이다.

그렇다면 왜 빈 배열은 첫 렌더링이 될 때만 호출되는가?
이는 첫 렌더링과 업데이트 된 렌더링의 차이점이 있기 때문이다. 첫 렌더링 때는 마운트라는 DOM트리 구조를 생성하는 단계를 거치지만, 단순 props, state의 변경에서는 마운트 과정이 생략되기 때문에 구분되는 것이다.

Clean Up 함수

Clean up 함수란 useEffect에서 파라미터로 넣은 함수의 return 함수이다. 이러한 상황은 두가지로 가능한데,

컴포넌트의 unmount 직전, update 직전에 작업을 수행하고 싶을 때 Clean up 함수를 반환해야 한다.

예제의 경우에는 unmount 될 때의 경우를 예시로 만들어 보았다.

//App.js
import React, { useState } from "react";
import Timer from "./components/Timer";

function App() {
  const [showTimer, setShowTimer] = useState(false);
  return (
    <>
      {showTimer && <Timer />}
      <button onClick={() => setShowTimer(!showTimer)}>토글 타이머</button>
    </>
  );
}

export default App;
// Timer.js
import React, { useEffect } from "react";

const Timer = (props) => {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log("타이머 작동 중");
    }, 1000);
  }, []);
  return (
    <div>
      <span>타이머를 시작합니다. 콘솔창을 확인하세요.</span>
    </div>
  );
};

export default Timer;

이 코드는 첫 렌더링이 일어나고 최초로 한번 Timer가 작동하는 코드이다.

콘솔창을 켜고 토글 타이머 버튼을 누르게 되면 계속해서 콘솔창에 타이머 작동 중이 나올 것이다. 그리고 다시 버튼을 누르게 된다면 Timer 컴포넌트는 사라질 것이다.

그런데 버튼을 다시 눌러서 사라지게 해도 콘솔창에는 계속해서 타이머가 작동중이다. 왜냐하면 우리가 setInterval() 함수를 사용하고 종료시키지 않았기 때문이다. 이를 해결하는 방법은 return 값으로 종료시키는 함수를 넣어주면 된다.

// Timer.js

import React, { useEffect } from "react";

const Timer = (props) => {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log("타이머 작동 중");
    }, 1000);

    return () => {
      clearInterval(timer);
      console.log("타이머 종료");
    };
  }, []);
  return (
    <div>
      <span>타이머를 시작합니다. 콘솔창을 확인하세요.</span>
    </div>
  );
};

export default Timer;

이렇게 리턴값으로 종료해주는 함수를 넣어준다면 계속 타이머가 돌아가지 않고 종료되는 것을 확인할 수 있다.

profile
기억보다는 기록하는 개발자

0개의 댓글