useEffect()

1. ๊ฐœ์š”

๋ฆฌ์•กํŠธ์—์„œ useState()๊ณผ ํ•จ๊ป˜ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” Hook์€ useEffect()์ด๋‹ค. useEffect()๋Š” ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋žœ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ํŠน์ • ์ž‘์—…์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์›€์„ ์ค€๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ(componentDidMount, componentDidUpdate, compoenntWillUnMount)์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด๋‹ค.


2. useEffect() ์‚ฌ์šฉํ•˜๊ธฐ

๊ธฐ๋ณธํ˜•ํƒœ useEffect(function, deps)

  • function: ์ˆ˜ํ–‰ํ•˜๊ณ ์ž ํ•˜๋Š” ์ž‘์—…

  • deps: ๋ฐฐ์—ด ํ˜•ํƒœ์ด๋ฉฐ, ๋ฐฐ์—ด ์•ˆ์—๋Š” ๊ฒ€์‚ฌํ•˜๊ณ ์ž ํ•˜๋Š” ํŠน์ • ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฑฐ๋‚˜ ๋˜๋Š” ๋นˆ ๋ฐฐ์—ด์ด๋‹ค.

์•„๋ž˜๋Š” ๊ฐ„๋‹จํ•œ useEffect()์˜ ์‚ฌ์šฉ์˜ˆ์‹œ์ด๋‹ค.

import React, { useEffect } from 'react';

const App = () => {
  useEffect(() => {
    consolo.log('Hello useEffect()!');
  }, []);
  return <div></div>;
};

export default App;

3. ๋งˆ์šดํŠธ

์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋‚˜ํƒ€๋‚ฌ์„ ๋•Œ(๋งˆ์šดํŠธ ๋˜์—ˆ์„ ๋•Œ)๋ฅผ useEffect()๋กœ ๊ด€๋ฆฌ๋ฅผ ํ•ด๋ณด์ž.

deps ๋ฐฐ์—ด์„ ๋น„์šฐ๊ฒŒ ๋œ๋‹ค๋ฉด, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋‚˜ํƒ€๋‚ ๋•Œ์—๋งŒ useEffect() ์— ๋“ฑ๋กํ•œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์˜ˆ์‹œ๋กœ ์‚ดํŽด๋ณด์ž.

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

const Test = () => {
  const [numberArr, setNumberArr] = useState([]);
  const onClickBtn = () => {
    const num = Math.floor(Math.random() * 100);
    const newNumArr = [...numberArr, num];
    setNumberArr(newNumArr);
  };
  return (
    <div>
      <button onClick={onClickBtn}>์ˆซ์ž ์ƒ์„ฑ</button>
      {numberArr.map((item, index) => {
        return <Number key={index} number={item} />;
      })}
    </div>
  );
};

export default Test;

const Number = ({ number }) => {
  useEffect(() => {
    console.log(`์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ${number}`);
  }, []);
  return <div>Number: {number}</div>;
};

์œ„์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ดํŽด๋ณด์ž. Test์ปดํฌ๋„ŒํŠธ์—์„œ ์ˆซ์ž ์ƒ์„ฑ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ƒˆ๋กœ์šด ์ˆซ์ž์ด ์ƒ๊ธฐ๊ณ  numberArr์— ์ƒˆ๋กœ์šด ์ˆซ์ž๊ฐ€ ๋‹ด๊ธฐ๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  numberArr์— ๋”ฐ๋ผ Number ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋œ๋‹ค.

Number์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ(๋งˆ์šดํŠธ)๋  ๋•Œ useEffect()๋กœ ์ธํ•ด ์ฝ˜์†”์ด ์ฐํžˆ๊ฒŒ ๋œ๋‹ค. ์•„๋ž˜๋Š” ์ˆซ์ž๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๋ณด์—ฌ์ง€๋Š” ํ™”๋ฉด๊ณผ ์ฝ˜์†”์ด๋‹ค.


4. ์–ธ๋งˆ์šดํŠธ

์ด๋ฒˆ์—๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ(์–ธ๋งˆ์šดํŠธ ๋˜์—ˆ์„ ๋•Œ)๋ฅผ useEffect()๋กœ ๊ด€๋ฆฌ๋ฅผ ํ•ด๋ณด์ž.

useEffect()์—์„œ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด ํ•จ์ˆ˜๋ฅผ cleanupํ•จ์ˆ˜๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ์ด cleanupํ•จ์ˆ˜๊ฐ€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ ํ˜ธ์ถœ๋œ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด cleanupํ•จ์ˆ˜๊ฐ€ useEffect()์— ๋Œ€ํ•œ ๋’ท์ •๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

cleanupํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์ž. ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์œ„์˜ Test์ปดํฌ๋„ŒํŠธ์— ์ถ”๊ฐ€์ ์ธ ์ฝ”๋“œ(Test์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ, cleanupํ•จ์ˆ˜ ์ฝ”๋“œ)๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด๋ณด์ž.

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

const Test = () => {
  const [numberArr, setNumberArr] = useState([]);
  const onClickBtn = () => {
    const num = Math.floor(Math.random() * 100);
    const newNumArr = [...numberArr, num];
    setNumberArr(newNumArr);
  };
  return (
    <div>
      <button onClick={onClickBtn}>์ˆซ์ž ์ƒ์„ฑ</button>
      {numberArr.map((item, index) => {
        return (
          <Number
            key={index}
            number={item}
            numberArr={numberArr}
            setNumberArr={setNumberArr}
          />
        );
      })}
    </div>
  );
};

export default Test;

const Number = ({ number, numberArr, setNumberArr }) => {
  // Number์ปดํฌ๋„ŒํŠธ๋ฅผ ์–ธ๋งˆ์šดํŠธํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜
  // setNumberArr๋ฅผ ํ†ตํ•ด numberArr์˜ ๊ฐ’์„ ๋ฐ”๊พผ๋‹ค.
  const onClickDelBtn = () => {
    const newNumArr = numberArr.filter((item) => item !== number);
    setNumberArr(newNumArr);
  };
  useEffect(() => {
    console.log(`์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ${number}`);

    // cleanup ํ•จ์ˆ˜
    return () => {
      console.log(`์ปดํฌ๋„ŒํŠธ ์–ธ๋งˆ์šด๋“œ ${number}`);
    };
  }, []);
  return (
    <div>
      <span>Number: {number}</span>
      <button onClick={onClickDelBtn}>์ˆซ์ž ์ง€์šฐ๊ธฐ</button>
    </div>
  );
};

5. deps ์— ํŠน์ • ๊ฐ’ ๋„ฃ๊ธฐ

deps์— ํŠน์ • ๊ฐ’์„ ๋„ฃ๊ฒŒ ๋œ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ ๋  ๋•Œ useEffect()๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  deps์— ๋„ฃ์€ ํŠน์ • ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ์—๋„ useEffect()๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด์„œ deps์— ํŠน์ •๊ฐ’์ด ์žˆ์„ ๋•Œ์™€ ์—†์„ ๋•Œ์˜ useEffect()๋ฅผ ๋น„๊ตํ•ด๋ณด์ง€.

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

const Test = () => {
  const [number, setNumber] = useState(1);

  const onClickChangeBtn = () => {
    const num = Math.floor(Math.random() * 100);
    setNumber(num);
  };

  // ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋  ๋•Œ๋งŒ ์‹คํ–‰
  useEffect(() => {
    console.log('์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ');
  }, []);

  // ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋˜๋Š” ์—…๋ฐ์ดํŠธ ๋  ๋•Œ ์‹ค์ƒ
  useEffect(() => {
    console.log(`์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ ์—…๋ฐ์ดํŠธ ${number}`);
  }, [number]);
  return (
    <div>
      <span>Number: {number}</span>
      <button onClick={onClickChangeBtn}>์ˆซ์ž ๋ฐ”๊พธ๊ธฐ</button>
    </div>
  );
};

export default Test;

์œ„์˜ ์ฝ”๋“œ์—์„œ useEffect()๊ฐ€ ๋‘ ๋ฒˆ ๋ณด์ธ๋‹ค. ๋ณด์ด๋Š” ์ˆœ์„œ๋Œ€๋กœ 1๋ฒˆ useEffect(), 2๋ฒˆ useEffect()๋ผ๊ณ  ๋ถ€๋ฅด๊ฒ ๋‹ค.

1๋ฒˆ useEffect()์˜ deps์€ ํŠน์ • ๊ฐ’์ด ์—†์€ ๋นˆ ๋ฐฐ์—ด์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜์Œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งŒ ํ˜ธ์ถœ์ด ๋œ๋‹ค. 2๋ฒˆ useEffect()์˜ deps์—๋Š” number๊ฐ’์ด ๋“ค์–ด๊ฐ€์žˆ๋‹ค. number์˜ ๊ฐ’์€ ์ˆซ์ž ๋ฐ”๊พธ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ ๋งˆ๋‹ค ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์— 2๋ฒˆ useEffect()๋Š” ์ˆซ์ž ๋ฐ”๊พธ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ number๊ฐ’์ด ๋ฐ”๋€” ๋•Œ ๋•Œ ๋งˆ๋‹ค ํ˜ธ์ถœ์ด ๋œ๋‹ค.

์•„๋ž˜๋Š” ์ˆซ์ž ๋ฐ”๊พธ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ฅผ ๋•Œ ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” useEffect()์˜ ๊ฒฐ๊ณผ ์‚ฌ์ง„์ด๋‹ค.


6. deps ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ƒ๋žตํ•˜๊ธฐ

useEffect()์˜ deps์˜ ์ž์ฒด๋ฅผ ์ƒ๋žตํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋  ๋•Œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฆฌ๋žœ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค useEffect()๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

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

const Test = () => {
  const [number, setNumber] = useState(1);

  const onClickChangeBtn = () => {
    const num = Math.floor(Math.random() * 100);
    setNumber(num);
  };

  useEffect(() => {
    console.log('์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ๋˜๋Š” ๋ฆฌ๋žœ๋”๋ง');
  });

  return (
    <div>
      <span>Number: {number}</span>
      <button onClick={onClickChangeBtn}>์ˆซ์ž ๋ฐ”๊พธ๊ธฐ</button>
    </div>
  );
};

export default Test;

์œ„์˜ ์ฝ”๋“œ์—์„œ ์ˆซ์ž ๋ฐ”๊พธ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ ๋งˆ๋‹ค number๊ฐ’์ด ๋ฐ”๊พธ๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ณ„์† ๋ฆฌ๋žœ๋”๋ง ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  useEffect()๋ฅผ ๋ณด๋ฉด deps๊ฐ€ ์™„์ „ํžˆ ์ƒ๋žต๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋žœ๋”๋ง ๋  ๋•Œ ๋งˆ๋‹ค useEffect()๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ๋‹ค์‹œ ๋งํ•ด ํ๋ฆ„์„ ์ •๋ฆฌํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. ์ˆซ์ž ๋ฐ”๊พธ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ๋‹ค.

  2. number๊ฐ’์ด ๋ฐ”๋€๋‹ค.

  3. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋žœ๋”๋ง ๋œ๋‹ค.

  4. useEffect()๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

์•„๋ž˜๋Š” ์ˆซ์ž ๋ฐ”๊พธ๊ธฐ ๋ฒ„ํŠผ๋ฅผ ๋ˆ„๋ฅผ ๋•Œ ๋งˆ๋‹ค useEffect()๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ๊ณ„์† ์ฐํžˆ๋Š” ์ฝ˜์†”์˜ ์‚ฌ์ง„์ด๋‹ค.


7. Conclusion

useEffect()๋ฅผ ์ž์ฃผ ์‚ฌ์šฉํ–ˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ lifecycle๊ณผ๋Š” ์—ฐ๊ด€์„ ์ง€์–ด ์ƒ๊ฐ์„ ํ•˜์ง€ ์•Š์•˜๋‹ค. ์ด๋ฒˆ ๊ณต๋ถ€๋ฅผ ํ†ตํ•ด lifecycle๊ณผ ์—ฐ๊ด€์„ ์ง€์–ด ์ดํ•ดํ•˜๋„๋ก ๋…ธ๋ ฅ์„ ํ–ˆ๊ณ , cleanupํ•จ์ˆ˜์— ๋Œ€ํ•ด์„œ๋„ ๋ง‰์—ฐํ•˜๊ฒŒ ์•Œ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์–ด๋–จ ๋•Œ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ณต๋ถ€์˜€๋‹ค.


์ฐธ๊ณ 

[React] ๋ฆฌ์•กํŠธ Hooks : useEffect() ํ•จ์ˆ˜ ์‚ฌ์šฉ๋ฒ• 16. useEffect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ์šดํŠธ/์–ธ๋งˆ์šดํŠธ/์—…๋ฐ์ดํŠธ์‹œ ํ•  ์ž‘์—… ์„ค์ •ํ•˜๊ธฐ


๐Ÿ‘†

๐Ÿ“… 2022-07-31

Last updated