์ฃผ์š” ์ž‘์—…

  • ํด๋ผ์ด์–ธํŠธ
    • ์Šคํƒ€์ผ ์ž‘์—…
    • useEffect๋ฅผ ํ†ตํ•œ data fetch
    • api ํ˜ธ์ถœ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋ฆฌ๋ Œ๋”๋ง์‹œํ‚ค๊ธฐ
    • ๋กœ๋”ฉ์ค‘์—๋Š” ๋กœ๋”ฉ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฌธ๊ตฌ ๋„์šฐ๊ธฐ
  • ์„œ๋ฒ„
    • ๋ฐฐํฌ
    • date ๊ฐ’์„ ์ถ”๊ฐ€ํ•ด์„œ ๋‚ ์งœ์ˆœ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋„๋ก ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„
    • ๋นŒ๋“œํ•œ ์ •์  ํŒŒ์ผ์„ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„ํ•˜์—ฌ ์„œ๋ฒ„์—์„œ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • useEffect ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„(ํ”„๋กœํ† ํƒ€์ž…)
    • root์—์„œ useEffect๋ฅผ ๊ด€๋ฆฌ

ํ•™์Šต ํ‚ค์›Œ๋“œ

  • ์†Œ์Šค๋งต
  • useEffect

๊ณ ๋ฏผ ๋ฐ ํ•ด๊ฒฐ๊ณผ์ •

useEffect์˜ ๋กœ์ง ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„

useEffect์˜ ๊ฒฝ์šฐ ๊ฐ€์žฅ ๋จผ์ € ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ๊ฐํ–ˆ๋˜ ๋ฐฉ๋ฒ•์€, state์ฒ˜๋Ÿผ root์— useEffect์˜ ์ฝœ๋ฐฑ์„ ๋“ฑ๋กํ•ด๋†“๊ณ , ๋ Œ๋”๋ง ๋  ๋•Œ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์—ˆ๋‹ค.

๋”ฐ๋ผ์„œ useEffect ๋˜ํ•œ ํฌ์ธํ„ฐ๋ฅผ ์˜ฎ๊ฒจ๊ฐ€๋ฉด์„œ ๊ณ„์†ํ•ด์„œ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋†“๊ณ , ๋ Œ๋”๋ง์ด ๋๋‚œ ๋’ค root์— ๋“ฑ๋ก๋˜์–ด์žˆ๋Š” ๋ชจ๋“  useEffect์— ๋Œ€ํ•ด์„œ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค.

async function fetchData() {
    const data = await apicall.get("/todo");
    setTodoList(data);
  }
 
  mhReact.useEffect(async () => {
    await fetchData();
  }, []);

ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜์™€ ๊ฐ™์ด, useEffect๋‚ด์—์„œ fetchDataํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ , ๋ฐ›์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด์„œ setterํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ƒˆ๋กญ๊ฒŒ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋†“์•˜๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ์—, useEffect ๋‚ด์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ commit์ด ๋๋‚œ ํ›„ ์‹คํ–‰์ด ๋˜๋ฉด, useEffect ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜๋ฉด์„œ setterํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ๊ธˆ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹คํ–‰์‹œ์ผฐ๊ณ , ๋ฆฌ๋ Œ๋”๋ง์ด ๋‹ค์‹œ ๋˜๊ณ  ๋‚œ ํ›„์—๋Š” ๋‹ค์‹œ๊ธˆ useEffect๋‚ด์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์‹คํ–‰ โ†’ ๋ฆฌ๋ Œ๋”๋ง โ†’ useEffect ์ฝœ๋ฐฑ ์‹คํ–‰โ€ฆ์˜ ๋ฌดํ•œ ๋ฃจํ”„๊ฐ€ ๋˜์—ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ์ด๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰ํ•˜๋ฉด ์ข‹์„๊นŒ? ๋ผ๋Š” ๊ณ ๋ฏผ์„ ํ–ˆ์—ˆ๋Š”๋ฐ ํ˜„์žฌ๋กœ์„œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒ๊ฐ์€ ์‹คํ–‰ ํ”Œ๋ž˜๊ทธ๋ฅผ ๋†“๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

import { Root } from "../dom/DomRoot";
 
/**
 *
 * @param {function} callbackFn
 * * @param {[]} dependencies
 */
export function useEffect(callbackFn, dependencies) {
  const root = Root();
  if (!root.global.hasOwnProperty("effects")) {
    root.global.effects = {};
    root.global.effectsIdx = 0;
  }
  const effectInformation = {
    fn: null,
    prev: null,
    dependencies: null,
    called: false,
  };
  effectInformation.fn = callbackFn;
  effectInformation.prev = dependencies;
 
  effectInformation.dependencies = dependencies;
 
  const index = root.global.effectsIdx;
  root.global.effects[index] = effectInformation;
  root.global.effectsIdx++;
}

called๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ๋†“๊ณ  ๊ฐ์ฒด ์ž์ฒด๋ฅผ effect๋กœ ๊ด€๋ฆฌํ–ˆ๋‹ค. ํ•œ๋ฒˆ ๋ Œ๋”๋ง์ด ๋˜๋ฉด called๊ฐ€ true๋กœ ๋ฐ”๋€Œ๊ณ , true๋œ ํ•จ์ˆ˜์— ๋Œ€ํ•ด์„œ๋Š” ์‹คํ–‰์‹œํ‚ค์ง€ ์•Š๊ณ  flag์˜ ๊ฐ’๋งŒ false๋กœ ๋‹ค์‹œ ๋ฐ”๊พธ๋Š” ๋ฐฉ์‹์„ ํ†ตํ•ด ์ตœ์ดˆ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค.

์ด ์™ธ์˜ prev๋‚˜ dependencies๊ฐ™์€ ๊ฒฝ์šฐ๋Š” Dependencies์— ์žˆ๋Š” ๊ฐ’์ด prev๊ฐ’๊ณผ ๋ณ€ํ•˜๋ฉด ๋ฆฌ๋ Œ๋”๋ง์ด ์ด๋ฃจ์–ด์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋Š”๋ฐ, ์•„์ง๊นŒ์ง€ ์ด๋Š” ๋ณด์™„๋˜์ง€๋Š” ์•Š์•˜๊ณ  ๊ณ„์†ํ•ด์„œ ๋ณด์™„ํ•  ์˜ˆ์ •์ด๋‹ค.