2024-03-12.md

๐Ÿก

DIL: ๋ชจ๋˜ ๋ฆฌ์•กํŠธ ๋”ฅ ๋‹ค์ด๋ธŒ, 2์ฃผ์ฐจ-2

์Šคํ„ฐ๋””: ์›”๊ฐ„ CS, https://github.com/monthly-cs/2024-03-modern-react-deep-dive
์˜ค๋Š˜ ์ง„ํ–‰: ๊ฐœ์ธ๊ณต๋ถ€


DIL-week2-2_2024-03-12

| DIL ์ฃผ์ฐจ | ๋ฒ”์œ„ | ๋‚ด์šฉ | ์˜ค๋Š˜์ฐจ ์ง„๋„ | | -------- | ------ | ------------------------------ | ----------- | | 2์ฃผ์ฐจ | 3, 5์žฅ | ๋ฆฌ์•กํŠธ ํ›…๊ณผ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ | 194p~207p |

์˜ค๋Š˜ ์ฝ์€ ๋‚ด์šฉ์„ markdown์œผ๋กœ ๊ฐ„๋‹จํžˆ ๋ฉ”๋ชจ
์ฝ์€ ์‹œ๊ฐ„: 11์‹œ~12์‹œ
๊ฐ๊ธฐ ์ด์Šˆ๐Ÿค•


React Hook ํŒŒํ—ค์น˜๊ธฐ

useState

๊ฒŒ์œผ๋ฅธ ์ดˆ๊ธฐํ™”๋ž€? lazy initialization

  • useState์˜ ์ดˆ๊นƒ๊ฐ’์ด ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ๋ฌด๊ฑฐ์šด ์—ฐ์‚ฐ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์„ ๋•Œ ์‚ฌ์šฉ
    • ๊ฒŒ์œผ๋ฅธ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋Š” state๊ฐ€ ์ฒ˜์Œ ๋งŒ๋“ค์–ด์งˆ ๋•Œ๋งŒ ์‚ฌ์šฉ๋œ๋‹ค(์ดํ›„ ํ•จ์ˆ˜์˜ ์‹คํ–‰์€ ๋ฌด์‹œ๋œ๋‹ค)
  • ์ถ”์ฒœ ์ผ€์ด์Šค (์‹คํ–‰ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ฒฝ์šฐ)
    • localStorage, sessionStorage ์ ‘๊ทผ
    • ๋ฐฐ์—ด ์ ‘๊ทผ: map, filter, find
    • ์ดˆ๊ธฐ๊ฐ’ ๊ฒŒ์‚ฐ์— ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ํ•„์š”ํ•  ๋•Œ

useEffect

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ’๋“ค์„ ํ™œ์šฉํ•˜์—ฌ ๋™๊ธฐ์ ์œผ๋กœ ๋ถ€์ˆ˜ ํšจ๊ณผ๋ฅผ ๋งŒ๋“ ๋‹ค. side-effects
  • ์–ด๋–ป๊ฒŒ ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋ณ€๊ฒฝ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‚˜?
    • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” => ๋งค๋ฒˆ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ด ๋žœ๋”๋ง์„ ์ˆ˜ํ–‰ํ•œ๋‹ค
    • ๋žœ๋”๋ง ์‹œ๋งˆ๋‹ค ๊ณ ์œ ์˜ state, props ๊ฐ’์„ ๊ฐ–๊ณ  ์žˆ์Œ
  • useEffect๋Š”? ํ‰๋ฒ”ํ•œ ํ•จ์ˆ˜๋‹ค
    • ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ๊ฒƒ์ด ์•„๋‹˜ like proxy, ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ, ์˜ต์ €๋ฒ„
    • state๊ณผ props ๋ณ€ํ™” > ๋žœ๋”๋ง > ๋ถ€์ˆ˜ ํšจ๊ณผ

ํด๋ฆฐ์—… ํ•จ์ˆ˜ clean-up function

  • ํด๋ฆฐ์—… ํ•จ์ˆ˜๋Š”? => ์ด์ „ state์„ ์ฐธ์กฐํ•ด ์‹คํ–‰๋œ๋‹ค
    • (์‹œ๊ธฐ) ํด๋ฆฐ์—… ํ•จ์ˆ˜๋Š” ์ƒˆ๋กœ์šด ๊ฐ’๊ณผ ํ•จ๊ป˜ ๋žœ๋”๋ง๋œ ๋’ค์— ์‹คํ–‰๋œ๋‹ค
    • (๊ฐ’) ํด๋ฆฐ์—… ํ•จ์ˆ˜๋Š” ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ฝ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•จ์ˆ˜๊ฐ€ ์ •์˜๋์„ ๋‹น์‹œ์— ์„ ์–ธ๋๋˜ ์ด์ „ ๊ฐ’์„ ๋ณด๊ณ  ์‹คํ–‰๋œ๋‹ค
  • useEffect๋Š” ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋  ๋•Œ => ํด๋ฆฐ์—… ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด ํด๋ฆฐ์—… ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์ฝœ๋ฐฑ์„ ์‹คํ–‰
    • unmount๊ฐ€ ์•„๋‹˜!
    • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋žœ๋”๋ง ๋์„ ๋•Œ, ์˜์กด์„ฑ ๋ณ€ํ™”๊ฐ€ ์žˆ์—ˆ์„ ๋‹น์‹œ ์ด์ „์˜ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์‹คํ–‰๋˜๋Š” => ์ฒญ์†Œ ๊ฐœ๋…~!

์˜์กด์„ฑ ๋ฐฐ์—ด

  • useEffect๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์˜ ์ด์ „ ๊ฐ’๊ณผ ํ˜„์žฌ ๊ฐ’์„ ์–•์€ ๋น„๊ตํ•œ๋‹ค.(Object.is)
  • ํ•˜๋‚˜๋ผ๋„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ๋‹ค๋ฉด, callback์œผ๋กœ ์„ ์–ธํ•œ ๋ถ€์ˆ˜ ํšจ๊ณผ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

์˜์กด์„ฑ ๋ฐฐ์—ด ์ž์ฒด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ

  • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋žœ๋”๋ง ๋๋Š”์ง€ ํ™•์ธ์šฉ
  • ๊ทธ๋ƒฅ useEffect ์—†์ด ์“ฐ๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹˜?
  1. ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋žœ๋”๋ง ๊ด€์ 

    • ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค
    • ์ฆ‰, window ๊ฐ์ฒด์— ์ ‘๊ทผ์— ์˜์กดํ•˜๋Š” ์ฝ”๋“œ ok
  2. useEffect๋Š” ์ปดํฌ๋„ŒํŠธ ๋žœ๋”๋ง(side effect)์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ์‹คํ–‰๋œ๋‹ค

    • ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•  ์‹œ, ๋žœ๋”๋ง ๋„์ค‘์— ์‹คํ–‰๋œ๋‹ค
    • (์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋žœ๋”๋ง์˜ ๊ฒฝ์šฐ, ์„œ๋ฒ„์—์„œ ์‹คํ–‰)
    • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ˜ํ™˜์„ ์ง€์—ฐ์‹œํ‚จ๋‹ค. ๋ฌด๊ฑฐ์šด ์ž‘์—…์ผ ๊ฒฝ์šฐ ๋žœ๋”๋ง์„ ๋ฐฉํ•ด, ์„ฑ๋Šฅ ์ €ํ•˜

์ฃผ์˜ํ•  ์ : ์˜์กด์„ฑ ๋ฐฐ์—ด์— ๋นˆ ๋ฐฐ์—ด์„ ๊ณ ์ง‘ํ•˜๋ฉด ์•ˆ๋˜๋Š” ์ด์œ 

  • eslint-disable-line react-hook/exhaustive-deps
  1. ์ ‘๊ทผ๋ฒ•์˜ ๋ฌธ์ œ
    • ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•˜๋Š” ์‹œ์ ์—๋งŒ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ๋‹ค?
    • componentDidMount์— ๊ธฐ๋ฐ˜ํ•œ ์ ‘๊ทผ๋ฒ•์œผ๋กœ, ์‚ฌ์šฉํ•ด์„  ์•ˆ๋จ
  2. side effect
    • ์ปดํฌ๋„ŒํŠธ์˜ state, props์˜ ๊ฐ’ ๋ณ€๊ฒฝ๊ณผ, ๋ถ€์ˆ˜ ํšจ๊ณผ ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ ๊ณ ๋ฆฌ๊ฐ€ ๋Š์–ด์ง
      • ๋ถ€์ˆ˜ ํšจ๊ณผ๊ฐ€ ์‹ค์ œ๋กœ ๊ด€์ฐฐ๋˜์„œ ์‹คํ–‰๋˜์•ผ ํ•˜๋Š” ๊ฐ’๊ณผ ๋ณ„๊ฐœ๋กœ ์ž‘๋™๋จ
    • ๋ถ€์ˆ˜ ํšจ๊ณผ๊ฐ€ ๋ถ€์ˆ˜ ํšจ๊ณผ๊ฐ€ ์•„๋‹ˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ
  3. ๋กœ์ง์˜ ๋ฌธ์ œ ์ฒดํฌ
    • ์ •๋ง ๋ถ€์ˆ˜ ํšจ๊ณผ๊ฐ€ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ์™€ "๋ณ„๊ฐœ"๋กœ ์ž‘๋™ํ•ด์•ผ๋งŒ ํ•˜๋Š” ์ง€ ํ™•์ธ
    • ๋ถ€์ˆ˜ ํšจ๊ณผ์˜ ์‹คํ–‰ ์œ„์น˜๊ฐ€ ์ ์ ˆํ•œ ์ง€ ํ™•์ธ
      • ํ•„์š”ํ•˜๋‹ค๋ฉด, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ณ€๊ฒฝ๋œ ๊ฐ’์„ props๋กœ ์ „๋‹ฌ๋ฐ›๊ธฐ
      • ๋ถ€์ˆ˜ ํšจ๊ณผ์˜ ํ๋ฆ„์„ ๊ฑฐ์Šค๋ฅด์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

useEffect ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜(์ฝœ๋ฐฑ ํ•จ์ˆ˜)์— ํ•จ์ˆ˜๋ช… ๋ถ€์—ฌํ•˜๊ธฐ

  • ํ•ด๋‹น useEffect์˜ ๋ชฉ์ ์„ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ฑ…์ž„์„ ์ตœ์†Œํ•œ์œผ๋กœ ์ขํžŒ๋‹ค
useEffect(
  function logActiveUse() {
    logging(user.id);
  },
  [user.id]
);

๊ฑฐ๋Œ€ํ•œ useEffect X

  • ๋ถ€์ˆ˜ ํšจ๊ณผ๊ฐ€ ํฌ๋‹ค๋ฉด?
    • ๋žœ๋”๋ง์—๋Š” ์˜ํ–ฅ์„ ์ ๊ฒŒ ๋ฏธ์นœ๋‹ค (๋žœ๋”๋ง ์ดํ›„์— ์‹คํ–‰๋˜๋‹ˆ๊นŒ)
    • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค (๋žœ๋”๋ง ์‹œ ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋‹ˆ๊นŒ)
  • ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šด ์ˆ˜์ค€๊นŒ์ง€ ์ปค์ง„๋‹ค๋ฉด?
    • ์–ธ์ œ ๋ฐœ์ƒํ•˜๋Š” ์ง€ ์•Œ ์ˆ˜ ์—†์Œ
    • ์ตœ๋Œ€ํ•œ useCallback๊ณผ useMemo๋กœ ์ •์ œํ•œ ๋‚ด์šฉ๋งŒ useEffect์— ๋‹ด๋Š”๋‹ค.

๋ถˆํ•„์š”ํ•œ ์™ธ๋ถ€ ํ•จ์ˆ˜ x

  • useEffect ๋ฐ–์—์„œ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด?
    • ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง€๊ณ , ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง
  • useEffect ๋‚ด์—์„œ ์‚ฌ์šฉํ•  side effect๋ผ๋ฉด? => ๋‚ด๋ถ€์—์„œ ๋งŒ๋“ค์–ด์„œ ์ •์˜ํ•ด์„œ ์‚ฌ์šฉ

์™œ useEffect์˜ ์ฝœ๋ฐฑ ์ธ์ˆ˜๋Š” ๋น„๋™๊ธฐ๊ฐ€ ๋  ์ˆ˜ ์—†๋Š”๊ฐ€?

"๊ฐœ๋ฐœ์ž์˜ ํŽธ์˜"

  1. race condition of useEffect
    • ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์‘๋‹ต ์†๋„์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ์ด์ƒํ•  ์ˆ˜ ์žˆ๋‹ค
      • ์ƒํƒœ๋ณ€ํ™”A: ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— 10์ดˆ
      • ์ดํ›„ ์ƒํƒœ๋ณ€ํ™”B: ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— 1์ดˆ
      • race condition์ด ๋ฐœ์ƒํ•ด state์ด => B => A๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค
  2. cleanup ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์—†๋‹ค.

์˜ˆ์ œ - 207p

  • useEffect ๋‚ด๋ถ€์˜ async Function ์„ ์–ธ, ํ˜น์€ ๋น„๋™๊ธฐ IIFE
  • ํด๋ฆฐ์—… ํ•จ์ˆ˜์— ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ, Fetch์˜ ๊ฒฝ์šฐ abortController๋กœ ์š”์ฒญ ์ทจ์†Œ
function Component({ id }: { id: string }) {
  const [info, setInfo] = useState<number | null>(null);

  useEffect(() => {
    const controller = new AbortController();

    (async () => {
      const result = await fetchInfo(id, { signal: controller.signal });
      setInfo(await result.json());
    })();

    return () => controller.abort();
  }, [id]);

  return <></>;
}