TIL 51 / 52일차 : REACTJS 숙련 : React Hooks 2 - useEffect

minjun kim·2024년 11월 29일
2

1. useEffect

✨ useEFfect hook의 개념 매우매우 중요합니다.

1-1. useEffect 언제 사용하나요?

useEffect는 리액트 컴포넌트가 렌더링 된 이후마다,
특정 작업을 수행하도록 설정할 수 있는 Hook입니다.

어떤 컴포넌트가 화면에 보여졌을 때 내가 무언가를 실행하고 싶다면?
어떤 컴포넌트가 화면에서 사라졌을 때 무언가를 실행하고 싶다면?

=> useEffect를 이런 패턴에서 사용합니다.

1-2. 코드로 보는 useEffect의 기초!

// src/App.js

import React, { useEffect } from "react";

const App = () => {

  useEffect(() => {
		// 이 부분이 실행된다.
    console.log("hello useEffect");
  });

  return <div>Home</div>;
}

export default App;

브라우저에서 우리가 App 컴포넌트를 보는 순간,
App 컴포넌트가 화면에 렌더링 된 이후 useEffect 안에 있는 console.log가 실행됩니다.

컴포넌트가 렌더링 된 이후 실횡된다 이것이 useEffect의 핵심 기능입니다.

1-3. useEffect와 리렌더링 (re-rendering) 중요!

useEffectuseEffect가 속한 컴포넌트가 화면에 렌더링 된 이후 실행됩니다.
이런 useEffect의 특징에 우리가 의도하지 않은 동작을 경험할 수 있는데...

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

const App = () => {
  const [value, setValue] = useState("");

  useEffect(() => {
    console.log("hello useEffect");
  });

  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={(event) => {
          setValue(event.target.value);
		      console.log("value => ", value);
        }}
      />
    </div>
  );
}

export default App;

위의 코드를 보면 input이 있고 value 라는 state를 생성해 input과 연결되어 있습니다.
이렇게 구현할 때 브라우저에 input에 어떤 값을 입력하면

useEffect가 계속 실행되는 걸 확인할 수 있습니다.

여기서 한가지 더 확인할 부분은
onChange 부분에서 setValue 아래에 console.log(value)를 찍어본다면
변경 전 값이 나올지 변경 후 값이 나올지?

논리적으로 당연히 변경 후 값이 나와야하지만 살펴보면...

흐름의 순서는

1. input에 값을 입력한다.
2. value, 즉 state가 변경된다.
3. state가 변경되었기 때문에, App 컴포넌트가 리렌더링 된다.
4. 리렌더링 되었기 때문에 useEffect가 다시 실행된다.
5. 결국 1번 -> 5번 과정이 계속 순환된다.

콘솔이 한번만 찍히길 원했지만, input을 입력할 때마다 계속 찍히는 것 입니다.
이 부분을 다시 해결할 수 있는 방법은?

2. 의존성 배열

✨ useEffect hook의 동작 trigger, 의존성 배열이란?

2-1. 의존성 배열 (dependency array)란?

useEffect에는 의존성 배열이라는 것이 있는데
이 배열에 값을 넣으면 그 값이 바뀔 때만 useEffeect를 실행하게 할 수 있습니다.

// useEffect의 두번째 인자가 의존성 배열이 들어가는 곳 입니다.
useEffect(()=>{
	// 실행하고 싶은 함수
}, [의존성배열])

2-2. 의존성 배열 체험하기

이번엔 useEffect에 의존성 배열을 추가해서 확인해보겠습니다.

일단 의존성 배열안에 어떠한 값도 없이 빈 [] 배열을 넣는다면,
의존성 배열이 이 배열에 값을 넣으면 그 값이 바뀔 때만 실행되기 때문에
아무런 값도 들어있지 않으니

useEffect는 최초 렌더링 이후 딱 한번만 실행되고 그 이후로는 어떠한 일이 일어나도 실행이 돼서는 안됩니다.

// src/App.js

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

const App = () => {
  const [value, setValue] = useState("");
  useEffect(() => {
    console.log("hello useEffect");
  }, []); // 비어있는 의존성 배열

  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={(event) => {
          setValue(event.target.value);
        }}
      />
    </div>
  );
}

export default App;

이렇게 useEffect를 사용하는데, 어떤 함수를 컴포넌트가 렌더링 된 이후
단 한번만 실행하고 싶으면 의존성 배열을 [] 빈 상태로 만들면 됩니다.

2-3. 의존성 배열이 존재한다면?

빈 배열을 넣으면 최초 렌더링 이후에 useEffect가 실행되지 않는 걸 확인할 수 있었다.
그럼 이제 의존성 배열에 value를 넣어보면 valuestate
우리가 input을 입력할 때마다 그 값이 변하니 useEffect도 계속 실행이 됩니다.

// src/App.js

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

const App = () => {
  const [value, setValue] = useState("");
  useEffect(() => {
    console.log("hello useEffect");
  }, [value]); // value를 넣음

  return (
    <div>
      <input
        type="text"
        value={value}
        onChange={(event) => {
          setValue(event.target.value);
        }}
      />
    </div>
  );
}

export default App;

이걸 console.log로 찍어보면 2번씩 찍히게 되는데,
이건 useEffect로 인해 두번 실행된 것이 아니라, strict mode라는 개발 환경이라서 그렇게 보이는 것입니다.

3. clean up

✨ 컴포넌트가 unmount 될 때 동작하는 cleanup 함수에 대해 배웁니다.
✨ 현재 배우지 않은 패키지를 사용하기에 아래를 보고 학습에만 집중하시면 됩니다.

3-1. clean up이란?

컴포넌트가 나타났을 때 (렌더링됐을 때 = 함수 컴포넌트가 실행됐을 때) 동작하는 것은
useEffecteffect 함수 부분입니다.

그럼 컴포넌트가 사라졌을 때 무언가를 어떻게 실행하는지 알아봐야하는데
이 과정을 클린 업 clean up 이라고 표현합니다.

3-2. 클린 업 방법

useEffect 내부에 return 을 해주고 이 부분에 실행되길 원하는 함수를 넣으면 됩니다.

// src/App.js

import React, { useEffect } from "react";

const App = () => {

	useEffect(()=>{
		// 화면에 컴포넌트가 나타났을(mount) 때 실행하고자 하는 함수를 넣어주세요.

		return ()=>{
			// 화면에서 컴포넌트가 사라졌을(unmount) 때 실행하고자 하는 함수를 넣어주세요.
		}
	}, [])

	return <div>hello react!</div>
};

export default App;

3-3. 클린 업 활용

아래 코드에서 버튼을 누르면 useNavagiate에 의해서 /todos 로 이동하면서 outComponent 컴포넌트를 떠나는 것입니다.
그러면 화면에서 outComponent 컴포넌트가 사라질 것이고, useEffectreturn 부분이 실행됩니다.

// src/SokSae.js

import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";

const outComponent = () => {
  const nav = useNavigate();

  useEffect(() => {
    return () => {
      console.log(
        "컴포넌트 나가기"
      );
    };
  }, []);

  return (
    <button
      onClick={() => {
        nav("/todos");
      }}
    >
      컴포넌트 나가기
    </button>
  );
};

export default outComponent;

확인해보면 / 에서 /todos 로 잘 이동하고, 이 과정에서 clean up이 실행되었습니다.

다른 페이지로 이동해서 컴포넌트가 사라지고, 그에 따라 클린 업이 되는 과정을 집중할 것

3-4. 컴포넌트 라이프사이클 - 중요!

리액트 컴포넌트도 태어나고, 살아가고, 죽는 생애주기가 존재합니다.
클래스형 컴포넌트를 주로 사용했을 이전 버전에서는 생애주기와 관련된 여러 메서드가 존재했지만...

현재처럼 함수형 컴포넌트를 사용할 때는 useEffect를 주로 사용하여 핸들링합니다.

profile
react_7기

1개의 댓글

comment-user-thumbnail
2024년 12월 18일

우와 개멋지당 축하해여

답글 달기

관련 채용 정보