React useEffect

 React useEffect




useEffect를 사용하면 Mount(화면에 첫 렌더링), Update(재렌더링), Unmount(화면에서 사라질 때) 이 세가지 조건을 가지고 작업을 할 수 있습니다.

useEffect라는 이름은 이 훅이 부수 효과(Side Effect)를 관리 하기 때문에 붙여졌습니다.  그리고 기본적으로 useEffect는 모든 컴포넌트의 렌더링이 끝난 뒤에 실행됩니다.

useEffect를 쓰는 경우는 데이터를 가지고 와서 state에 담거나 setTime 같은 함수를 쓸 때이거나 무한루프에 빠지는것을 방지 하기 위해 많이 쓰입니다.

useEffect를 쓰지 않는다면 모든 컴포넌트의 렌더링이 끝난 뒤에 실행하기 때문에 데이터를 가지고와서 state에 담고 재렌더링이 된다면 재렌더링이 끝난후 useEffect를 실행하고 state에 담고 또 재렌더링이 되고 useEffect를 실행하면 무한루프에 빠집니다.

혹은 setTime 같은 함수를 쓰게되면 clean up을 할 수 없어서 해당 컴포넌트가 사라져도 setTime같은 함수는 계속해서 돌아가기 때문에 이것을 멈추기 위해 쓰입니다.

useEffect는 첫번째 인자에는 콜백함수를 받는데 콜백함수는 다른 함수에 인자로 전달된 함수를 의미합니다.

두번째 인자에는 배열을 받는데 이것을 dependency Array라고 부릅니다.

 
useEffect(() => {
    // 작업
  })

두번째 인자를 생략할 수도 있습니다. 이런 경우에는 재렌더링이 될 때마다 useEffect가 실행되기 때문에 성능이 저하될 수 있습니다.

 
useEffect(() => {
    // 작업
  },[value])

두번째 인자에는 배열이 들어간다고 위에서 설명했습니다. 배열에 어떠한 값이 들어간다면 그 값이 바뀔때에만 useEffect가 실행이 됩니다.

 
useEffect(() => {
    // 작업
  },[])

두번째 인자에 아무런 값을 넣지 않고 빈 배열만 입력하면 브라우저가 첫 렌더링(Mount)될때에만 useEffect가 실행 됩니다.

useEffect에서 어떠한 작업을 했다면 이 작업을 clean up이라는 작업(정리)을 해주어야 합니다.

useEffect에서 retrun 값으로 콜백함수를 넣고 그 안에서 작업을 정리(해지) 해주면 됩니다.

사용법은 useState와 마찬가지로 컴포넌트 바깥 최상위에서 import를 해줍니다.

훅함수는 컴포넌트 안에서만 쓸 수 있습니다.


import { useEffect, useState } from "react";

useEffect 사용법


import { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("");

  const addFn = () => {
    setCount(count + 1);
  };

  useEffect(() => {
    console.log("렌더링");
  });

  const nameFn = (e) => {
    setName(e.target.value);
  };

  return (
    <div className="App">
      <div>
        <button onClick={addFn}>+</button>
        <span>{count}</span>
      </div>
      <div>
        <span>이름: {name} </span>
        <input type="text" onChange={nameFn}></input>
      </div>
    </div>
  );
}

export default App;


두번째 인자가 없을 경우

렌더링이 될때마다 useEffect를 실행 하기 때문에 Mount(첫 화면 렌더링), Update(재렌더링)을 할 때마다 useEffect가 실행됩니다.

 
useEffect(() => {
    console.log("렌더링");
  });

버튼을 1씩 증가해도 useEffect가 실행되고 input에 글자 하나하나를 타이핑 할 때마다 useEffect가 실행됩니다.

만약 useEffect안에 무거운 코드가 있다면 성능면에서 굉장히 비효율적이게 됩니다.

두번째 인자가 있을 경우

여기서 count가 증가 할 때만 useEffect를 실행 시키려면  두번째 인자에 배열을 추가하고 배열안에  count 변수를 넣을 수 있습니다.

 
useEffect(() => {
    console.log("렌더링");
  }, [count]);

이렇게 하면 count가 update 될 때만 useEffect가 실행되고 name이 update가 되면 useEffect가 실행되지 않습니다. 

두번째 인자가 빈 배열일 경우

 
useEffect(() => {
    console.log("렌더링");
  }, []);

이렇게 하면 Mount(첫화면 렌더링)일 때에만 useEffect를 실행합니다. count나 input이 업데이트 되던지 말던지 아무런 영향이 없습니다.

보통 저는 포트폴리오를 만들 때에 저 3개 중에서 대부분 두번째 인자가 빈 배열일 경우에만 작업을 했어서 배열에 값이 있는 경우는 어떨 때 쓰이는지는 아직 모르겠지만 일단 useEffect가 React에서 자주 쓰이고 중요하기 때문에 언제 쓰일지 몰라 자세히 배워놓았습니다.

clean up


//component/Timer.jsx
import React, { useEffect } from "react";

const Timer = () => {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log("타이머 돌아가는중...");
    }, 1000);
  }, []);
  return (
    <div>
      <span>타이머를 시작.</span>
    </div>
  );
};

export default Timer;

Timer 컴포넌트를 따로 만들고 App.js에 불러옵니다.


//App.js
import { useState } from "react";
import "./App.css";
import Timer from "./component/Timer";

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

export default App;

이 코드는 button을 클릭 할 때마다 true, false가 바뀌게 됩니다.

showTimer가 true일 때만 Timer 컴포넌트가 보이고 false 일 때에는 사라지는 코드입니다.

하지만 console.log를 보면 setInterval은 Timer 컴포넌트가 사라져도 계속 돌아가고있습니다.

useEffect를 쓰는 컴포넌트가 10개, 100개, 1000개 라면 웹앱의 성능이 저하되기 때문에 꼭 useEffect에서 작업을 하면 clean up 작업을 해주어야 합니다.


const Timer = () => {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log("타이머 돌아가는중...");
    }, 1000);

    return () => {
      clearInterval(timer);
      console.log("타이머 종료");
    };
  }, []);

useEffect에서 콜백함수를 return으로 반환하게 되면 컴포넌트가 Unmount(화면에서 사라질때) 실행이 됩니다.

댓글

이 블로그의 인기 게시물

[정보처리기사] OSI 7계층 정리

블로그스팟 상위노출 시작하기

데이터베이스 데이터 정의어(DDL), 자료형(데이터 타입)