240818 React useEffect

์‹ ํ•œ๋ณ„ยท2024๋…„ 8์›” 17์ผ

๐Ÿ’ช ๋งค์ผ ๊ธฐ๋ก

๋ชฉ๋ก ๋ณด๊ธฐ
55/97

์˜์กด์„ฑ ๋ฐฐ์—ด ์•ˆ ์“ธ๊ฑฐ๋ฉด useEffect ์“ฐ์ง€๋งˆ!!!!!!!!

01. useEffect

(1) useEffect๋Š” ์–ธ์ œ ์‚ฌ์šฉํ•˜๋‚˜

๐Ÿ’ก useEffect๋ž€? ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋œ ์ดํ›„๋งˆ๋‹ค ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” Hook ์ด๋‹ค.
์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋œ ์ดํ›„ ์‹คํ–‰๋œ๋‹ค. ์ด๊ฒŒ ๋ฐ”๋กœ useEffect ํ•ต์‹ฌ ๊ธฐ๋Šฅ.

์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์— ๋ณด์—ฌ์กŒ์„ ๋•Œ ๋‚ด๊ฐ€ ๋ฌด์–ธ๊ฐ€๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?
๋˜๋Š” ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์กŒ์„ ๋•Œ ๋ฌด์–ธ๊ฐ€๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?
๐Ÿ“ข useEffect๋ฅผ ์‚ฌ์šฉ

useState์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ React์—์„œ ์ œ๊ณตํ•˜๋Š” ํ›… (๊ธฐ๋Šฅ) ์ด๋ฏ€๋กœ import ํ•ด์„œ ์‚ฌ์šฉ

import React, { useEffect } from "react";

(2) ์ฝ”๋“œ๋กœ ๋ณด๋Š” useEffect ๊ธฐ์ดˆ

๋ธŒ๋ผ์šฐ์ €์—์„œ ์šฐ๋ฆฌ๊ฐ€ App ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ˆˆ์œผ๋กœ ๋ณด๋Š” ์ˆœ๊ฐ„, ์ฆ‰ App ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์— ๋ Œ๋”๋ง ๋œ ์ดํ›„ useEffect ์•ˆ์— ์žˆ๋Š” console.log๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

// src/App.js

import React, { useEffect } from "react";

const App = () => {

  useEffect(() => {
		// ์ด ๋ถ€๋ถ„์ด ์‹คํ–‰๋œ๋‹ค.
    console.log("hello useEffect");
  });

  return <div>Home</div>;
}

export default App;

(3) useEffect์™€ ๋ฆฌ๋žœ๋”๋ง

useEffect๊ฐ€ ์†ํ•œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์— ๋žœ๋”๋ง ๋œ ์ดํ›„ ์‹คํ–‰๋˜๋Š” ํŠน์ง• ๋•Œ๋ฌธ์— ์˜๋„์น˜์•Š์€ ๋™์ž‘์„ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

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

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

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

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

export default App;

input์— ๊ฐ’์„ ์ž…๋ ฅํ•  ๋•Œ ๋งˆ๋‹ค ์ฝ˜์†”์ฐฝ์— ํ…์ŠคํŠธ๊ฐ€ ๊ณ„์† ์ƒ์„ฑ๋œ๋‹ค.

  1. input์— ๊ฐ’์„ ์ž…๋ ฅํ•œ๋‹ค.
  2. value, ์ฆ‰ state๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค. (setValue(event.target.value)๋กœ ์ธํ•ด)
  3. state๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, App ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค.
  4. ๋ฆฌ๋ Œ๋”๋ง์ด ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— useEffect๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค.
  5. 1๋ฒˆ โ†’ 5๋ฒˆ ๊ณผ์ •์ด ๊ณ„์† ์ˆœํ™˜ํ™˜๋‹ค.

๐Ÿ˜ต ๋„ˆ๋ฌด ๋‹นํ™ฉ์Šค๋Ÿฝ๋‹ค. ํ•˜์ง€๋งŒ? ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

02. ์˜์กด์„ฑ ๋ฐฐ์—ด (dependency array)

๐Ÿ“ข ๋ฐ˜๋“œ์‹œ ์•Œ์•„์•ผ ํ•˜๋Š” useEffect hook์˜ ๋™์ž‘ trigger, ์˜์กด์„ฑ ๋ฐฐ์—ด

(1) ์˜์กด์„ฑ ๋ฐฐ์—ด ์ด๋ž€

?? : โ€œ์ด ๋ฐฐ์—ด์— ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๊ทธ ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ๋งŒ useEffect๋ฅผ ์‹คํ–‰ํ• ๊ฒŒโ€

// useEffect์˜ ๋‘๋ฒˆ์งธ ์ธ์ž๊ฐ€ ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋“ค์–ด๊ฐ€๋Š” ๊ณณ ์ž…๋‹ˆ๋‹ค.
useEffect(()=>{
	// ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์€ ํ•จ์ˆ˜
}, [์˜์กด์„ฑ๋ฐฐ์—ด])

(2) ์ฝ”๋“œ๋กœ ๋ณด๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด -> ๋นˆ ๋ฐฐ์—ด์ธ ๊ฒฝ์šฐ

useEffect๋Š” ์ตœ์ดˆ ๋ Œ๋”๋ง ์ดํ›„ ๋”ฑ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๊ณ  ๊ทธ ์ดํ›„๋กœ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค!

๋‹น์—ฐํ•จ. ๋ฐฐ์—ด ์† ๊ฐ’์ด ๋ฐ”๋€Œ์–ด์•ผ useEffect๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ ๋นˆ๊ฐ’์ด๋ผ ๋ฐ”๋€”์ผ์ด ์—†์Œ.

(3) ์ฝ”๋“œ๋กœ ๋ณด๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด -> ๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ

useEffect๋„ ๊ณ„์† ์‹คํ–‰์ด ๋˜๊ฒ ์ฃ 

๋ฐฐ์—ด์— value๋ฅผ ๋„ฃ์–ด๋ณด๊ฒ ์‚ผ

// src/App.js

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

const App = () => {
  const [value, setValue] = useState("");
  useEffect(() => {
    console.log("HELLLO");
  }, [value]); // value๋ฅผ ๋„ฃ์Œ

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

export default App;

03. clean up

(1) ํด๋ฆฐ ์—… ์ด๋ž€?

์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์กŒ์„ ๋•Œ (unmount) ๋ฌด์–ธ๊ฐ€๋ฅผ ์–ด๋–ป๊ฒŒ ์‹คํ–‰ํ•˜๋Š”์ง€ => ํด๋ฆฐ ์—…(clean up)
useEffect์™€ ๋ฐ˜๋Œ€๋˜๋Š” ๊ฐœ๋…?! ๐Ÿ™‚

(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) ํด๋ฆฐ ์—… ํ™œ์šฉ

์†์„ธ๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋ฒ„ํŠผ ์„ ๋งŒ๋“ค์—ˆ๊ณ  ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด useNavigate์— ์˜ํ•ด์„œ /todos๋กœ ์ด๋™ํ•˜๋ฉด์„œ ์†์„ธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋– ๋‚  ๊ฒƒ์ด๋‹ค.
๊ทธ๋Ÿฌ๋ฉด์„œ ํ™”๋ฉด์—์„œ ์†์„ธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๊ฒƒ์ด๊ณ , useEffect์˜ return ๋ถ€๋ถ„์ด ์‹คํ–‰๋  ๊ฒƒ.

// src/SokSae.js

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

const ์†์„ธ = () => {
  const nav = useNavigate();

  useEffect(() => {
    /// ํด๋ฆฐ์—… ํ•จ์ˆ˜!
    return () => {
      console.log(
        "์•ˆ๋…•ํžˆ ๊ณ„์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„! ์ „ ์ด ์„ธ์ƒ์˜ ๋ชจ๋“  ๊ตด๋ ˆ์™€ ์†๋ฐ•์„ ๋ฒ—์–ด ๋˜์ง€๊ณ  ์ œ ํ–‰๋ณต์„ ์ฐพ์•„ ๋– ๋‚ฉ๋‹ˆ๋‹ค! ์—ฌ๋Ÿฌ๋ถ„๋„ ํ–‰๋ณตํ•˜์„ธ์š”~~!"
      );
    };
  }, []);

  return (
    <button
      onClick={() => {
        nav("/todos");
      }}
    >
      ์†์„ธ๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋ฒ„ํŠผ
    </button>
  );
};

export default ์†์„ธ;

(4) ์ปดํฌ๋„ŒํŠธ ๋ผ์ดํ”„์‚ฌ์ดํด

๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋„ ํƒœ์–ด๋‚˜๊ณ , ์‚ด์•„๊ฐ€๊ณ , ์ฃฝ๋Š” ์ƒ์• ์ฃผ๊ธฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค.

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ–ˆ์„ ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” ์ด ์ƒ์• ์ฃผ๊ธฐ์™€ ๊ด€๋ จ๋œ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ–ˆ์ง€๋งŒ,
ํ˜„์žฌ์ฒ˜๋Ÿผ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” useEffect๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ•ธ๋“ค๋งํ•œ๋‹ค.


์ถœ์ฒ˜ : Dev Community

0๊ฐœ์˜ ๋Œ“๊ธ€