๐Ÿ’ป ์ฝ”๋”ฉ ์ผ๊ธฐ : [React] 'useEffect' ํŽธ

ybkยท2024๋…„ 5์›” 15์ผ
0

react

๋ชฉ๋ก ๋ณด๊ธฐ
10/16
post-thumbnail

๐Ÿ””'useEffect'์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž!


๐Ÿ’Ÿ useEffect( )

useEffect : ํŠน์ • ์ˆœ๊ฐ„์— ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Initial Rendering(ํŠธ๋ฆฌ์— ๋ถ™์„ ๋•Œ, mount)๋  ๋•Œ, Re-Rendering๋  ๋•Œ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŠธ๋ฆฌ์—์„œ ๋–จ์–ด์งˆ ๋•Œ(unmount), ์–ด๋–ค state๊ฐ€ ๋ฐ”๋€” ๋•Œ(dependency ๋ณ€๊ฒฝ)์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ : ๋ถ€์ˆ˜ ํšจ๊ณผ๋ฅผ ํฌํ•จํ•œ ๋ฉ”์†Œ๋“œ์ž…๋‹ˆ๋‹ค.
  • ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ : dependency (ํŠน์ • ์ˆœ๊ฐ„), dependency ๋ฐฐ์—ด์— ํฌํ•จ๋œ ์ƒํƒœ๋‚˜ props ์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

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

function MyComp() {
  // ํŠน์ • ์ˆœ๊ฐ„์— ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์Œ
  useEffect(() => {
    console.log("re rendering ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰");
  });

  // ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ ๋นˆ ๋ฐฐ์—ด
  useEffect(() => {
    console.log("์ฒซ ๋ Œ๋”๋ง ๋•Œ๋งŒ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ");
  }, []);

  // ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ(ํ•จ์ˆ˜)์˜ ๋ฆฌํ„ด์€ unmount๋  ๋•Œ ์‹คํ–‰
  useEffect(() => {
    return () => {
      console.log("์–ธ๋งˆ์šดํŠธ ๋  ๋•Œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ");
    };
  }, []);

  // ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ(๋ฐฐ์—ด)์˜ ์›์†Œ
  // ์–ด๋–ค ๊ฐ’(์ฃผ๋กœ state, dependency)์ด ๋ฐ”๋€” ๋•Œ,
  const [text1, setText1] = useState("");
  const [text2, setText2] = useState("");
  useEffect(() => {
    console.log("dependency text1์ด ๋ฐ”๋€” ๋•Œ");
  }, [text1]);
  useEffect(() => {
    console.log("dependency text2์ด ๋ฐ”๋€” ๋•Œ");
  }, [text2]);
  useEffect(() => {
    console.log("text1 text2๊ฐ€ ๋ฐ”๋€” ๋•Œ");
  }, [text1, text2]);

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

  return (
    <div>
      hello comp
      <button onClick={() => setCount(count + 1)}>CLICK</button>
      <div>
        <input type="text" onChange={(e) => setText1(e.target.value)} />
      </div>
      <div>
        <input type="text" onChange={(e) => setText2(e.target.value)} />
      </div>
    </div>
  );
}

function App(props) {
  const [show, setShow] = useState(true);

  return (
    <div>
      <input
        type="checkbox"
        checked={show}
        onChange={(e) => setShow(e.target.checked)}
      />
      {show && <MyComp />}
    </div>
  );
}

export default App;
  1. Re-rendering ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” useEffect: ์ฒซ ๋ฒˆ์งธ useEffect๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ re-rendering ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์ฝ˜์†”์— "re rendering ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰"์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

  2. ์ฒซ ๋ Œ๋”๋ง ๋•Œ๋งŒ ์‹คํ–‰๋˜๋Š” useEffect: ๋‘ ๋ฒˆ์งธ useEffect๋Š” ๋นˆ ๋ฐฐ์—ด์„ ์˜์กด์„ฑ ๋ฐฐ์—ด๋กœ ์ „๋‹ฌํ•˜์—ฌ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋ Œ๋”๋ง๋  ๋•Œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํŽ˜์ด์ง€๊ฐ€ ์ฒ˜์Œ ๋กœ๋“œ๋  ๋•Œ ์ฝ˜์†”์— "์ฒซ ๋ Œ๋”๋ง ๋•Œ๋งŒ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ"๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

  3. Unmount ๋  ๋•Œ ์‹คํ–‰๋˜๋Š” useEffect: ์„ธ ๋ฒˆ์งธ useEffect๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธ๋  ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง ์‹œ์—๋งŒ ์กด์žฌํ•˜๋Š” MyComp ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์งˆ ๋•Œ ์ฝ˜์†”์— "์–ธ๋งˆ์šดํŠธ ๋  ๋•Œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ"๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

  4. Dependency์— ๋”ฐ๋ผ ์‹คํ–‰๋˜๋Š” useEffect: text1๊ณผ text2 ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๊ฐ๊ฐ์˜ useEffect๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ text1๊ณผ text2 ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” useEffect๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ input ์š”์†Œ์— ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ์ฝ˜์†”์— ํ•ด๋‹นํ•˜๋Š” ๋ฌธ๊ตฌ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ text1๊ณผ text2 ๋‘˜ ๋‹ค ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” useEffect๋„ ์žˆ์œผ๋ฏ€๋กœ, ๋‘ input ์š”์†Œ์— ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค "text1 text2๊ฐ€ ๋ฐ”๋€” ๋•Œ"๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“ข ์ฃผ์˜ํ•  ์  : useEffect ๋‚ด์—์„œ dependency๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

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

function App(props) {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("mount ๋  ๋•Œ");
  }, []);

  useEffect(() => {
    console.log("count๊ฐ€ ๋ณ€๊ฒฝ ๋  ๋•Œ");
    // dependency๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ์ฃผ์˜
    // setCount(count + 1); ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜ ์ž‘์„ฑ ๋ถˆ๊ฐ€๋Šฅ
  }, [count]);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>click</button>
    </div>
  );
}

export default App;
  1. ์ฒซ ๋ฒˆ์งธ useEffect:

    • ๋นˆ ๋ฐฐ์—ด []์„ ์˜์กด์„ฑ ๋ฐฐ์—ด๋กœ ์ „๋‹ฌํ•˜์˜€์œผ๋ฏ€๋กœ, ์ด useEffect๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
    • ๋”ฐ๋ผ์„œ ํŽ˜์ด์ง€๊ฐ€ ์ฒ˜์Œ ๋กœ๋“œ๋  ๋•Œ ์ฝ˜์†”์— "mount ๋  ๋•Œ"๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  2. ๋‘ ๋ฒˆ์งธ useEffect:

    • [count]๋ฅผ ์˜์กด์„ฑ ๋ฐฐ์—ด๋กœ ์ „๋‹ฌํ•˜์—ฌ, count ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ count ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ฝ˜์†”์— "count๊ฐ€ ๋ณ€๊ฒฝ ๋  ๋•Œ"๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
    • ์ฃผ์˜ํ•  ์ ์€ ์ด useEffect ๋‚ด์—์„œ setCount(count + 1)๊ณผ ๊ฐ™์ด count๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด setCount ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ re-renderํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌดํ•œ ๋ฃจํ”„์— ๋น ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
profile
๊ฐœ๋ฐœ์ž ์ค€๋น„์ƒ~

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