2024-04-09.md

๐Ÿก

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

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


DIL-week6-\2_2024-04-09

| DIL ์ฃผ์ฐจ | ๋ฒ”์œ„ | ๋‚ด์šฉ | ์˜ค๋Š˜์ฐจ ์ง„๋„ | | -------- | ---------- | --------------------------------------------------------- | ----------- | | 6์ฃผ์ฐจ | 10์žฅ, 11์žฅ | ๋ฆฌ์•กํŠธ 17๊ณผ 18 ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์‚ดํŽด๋ณด๊ธฐ, Next.js 13๊ณผ ๋ฆฌ์•กํŠธ 18 | 657~678p |

์˜ค๋Š˜ ์ฝ์€ ๋‚ด์šฉ์„ markdown์œผ๋กœ ๊ฐ„๋‹จํžˆ ๋ฉ”๋ชจ
์ฝ์€ ์‹œ๊ฐ„: 8์‹œ~9์‹œ, 10์‹œ20๋ถ„~11์‹œ10๋ถ„


๋ฆฌ์•กํŠธ 17๊ณผ 18 ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์‚ดํŽด๋ณด๊ธฐ

๋ฆฌ์•กํŠธ 17

  • 16 => 17
    • ๋ฆฌ์•กํŠธํŒ€ ์™ˆ, 10๋งŒ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ˜ธํ™˜์„ฑ์ด ๊นจ์ง€๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ 20๊ฐœ ๋ฏธ๋งŒ์ด๋ผ ํ•จ

์ ์ง„์  ์—…๊ทธ๋ ˆ์ด๋“œ

  • ๋ ˆ๊ฑฐ์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ด€๋ฆฌ > ์ง€์› ์ค‘๋‹จ๋œ API ๊ณ ์น˜๋Š” ์ž‘์—… > ๋ฒˆ๊ฑฐ๋กœ์›€
  • 17๋ถ€ํ„ฐ ์ผ๋ถ€ ํŠธ๋ฆฌ + ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด์„œ๋งŒ 18์„ ์„ ํƒํ•˜๋Š” "์ ์ง„์  ์—…๊ทธ๋ ˆ์ด๋“œ"๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค..
  • ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋ถ€๋‹ด์ด ๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ ๊ณ ๋ ค
    • ์ด๋Ÿฐ ์ด์œ ๋กœ 17๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ•œ๋‹ค๋ฉด ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์—…๋ฐ์ดํŠธ๋ผ ํ•  ์ˆ˜ ์žˆ์Œ

ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ ๋ฆฌ์•กํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค

  • https://github.com/wikibook/react-deep-dive-example/tree/main/chapter10/react-gradual-demo
    • mordern(17)๊ณผ legacy(16)๋กœ ๊ตฌ์„ฑ๋œ ์˜ˆ์ œ ๋ ˆํฌ
      • mordern ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด legacy ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ lazy๋กœ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
      • ๋ฆฌ์•กํŠธ 16์„ ์œ„ํ•œ ๋ฃจํŠธ ์š”์†Œ๋ฅผ ๋งŒ๋“œ๋Š” HOC lazyLegacyRoot
        • ๋žœ๋”๋ง ๊ณผ์ •์—์„œ ๋ฒ„์ „ ๋ถˆ์ผ์น˜๋กœ ์ธํ•œ ์—๋Ÿฌ ๋ฐœ์ƒx
        • ๋‘ ๊ฐœ์˜ ๋ฆฌ์•กํŠธ ๋ฃจํŠธ๋Š” -> ์ปดํฌ๋„ŒํŠธ, ํ›…, Context๋ฅผ ์„œ๋กœ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์–ด๋””๊นŒ์ง€๋‚˜ ์ฐจ์„ ์ฑ…

์ด๋ฒคํŠธ ์œ„์ž„ ๋ฐฉ์‹์˜ ๋ณ€๊ฒฝ๐Ÿค”

  • ์–ด๋–ป๊ฒŒ?
import { useEffect, useRef } from "react";

export default function Button() {
  const buttonRef = useRef<HTMLButtonElement | null>(null);

  useEffect(() => {
    if (buttonRef.current) {
      buttonRef.current.onclick = function ์ž๊ฐˆ์น˜() {
        alert("๐Ÿ™");
      };
    }
  }, []);

  function ์˜ค์‚ฌ์ฏ”() {
    alert("๐Ÿ ");
  }

  return (
    <>
      {/* ๋ฆฌ์•กํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ DOM์— onClick ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹ */}
      {/* handler: noop(), no operation, ์•”๊ฒƒ๋„ ํ•˜์ง€ ์•Š์Œ */}
      <button onClick={์˜ค์‚ฌ์ฏ”}>๋ฆฌ์•กํŠธ ๋ฒ„ํŠผ</button>

      {/* DOM์„ ์ฐธ์กฐํ•œ ๋‹ค์Œ, DOM์˜ onclick์— ์ง์ ‘ ํ•จ์ˆ˜ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณ ์ „์ ์ธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€ ๋ฐฉ์‹ */}
      {/* handler: ์ž๊ฐˆ์น˜() */}
      <button ref={buttonRef}>DOM ๋ฒ„ํŠผ</button>
    </>
  );
}

๋ฆฌ์•กํŠธ์™€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ, ์ด๋ฒคํŠธ ์œ„์ž„

  • ํ•ด๋‹น ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•œ ๊ฐ๊ฐ์˜ DOM ์š”์†Œ์— ๋ถ€์ฐฉx
  • ์ด๋ฒคํŠธ ํƒ€์ž…๋‹น ํ•˜๋‚˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฃจํŠธ์— ๋ถ€์ฐฉํ•œ๋‹ค
  • ์ด๋ฒคํŠธ ๊ตฌ์„ฑ ๋‹จ๊ณ„ | ๋‹จ๊ณ„ | ๋‚ด์šฉ | | --- | --- | | capture | ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํŠธ๋ฆฌ ์ตœ์ƒ๋‹จ ์š”์†Œ์—์„œ๋ถ€ํ„ฐ, ์‹ค์ œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ํƒ€๊นƒ ์š”์†Œ๊นŒ์ง€ ๋‚ด๋ ค๊ฐ€๋Š” ๊ฒƒ | | target | ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํƒ€๊นƒ ๋…ธ๋“œ์— ๋„๋‹ฌ / ์ด๋ฒคํŠธ ํ˜ธ์ถœ | | bubbling | ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์š”์†Œ์—์„œ๋ถ€ํ„ฐ ์ตœ์ƒ์œ„ ์š”์†Œ๊นŒ์ง€ ์˜ฌ๋ผ๊ฐ€๋Š” ๊ฒƒ |
  • ๋ฆฌ์•กํŠธ์˜ ๊ฒฝ์šฐ, ์ตœ์ดˆ ๋ฆด๋ฆฌ์ฆˆ๋ถ€ํ„ฐ event delegation์„ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ–ˆ๋‹ค. ์ด๋ฒคํŠธ๋ฅผ ๊ฐ ์š”์†Œ๊ฐ€ ์•„๋‹Œ document์— ์—ฐ๊ฒฐํ•ด์„œ ์ด๋ฒคํŠธ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
    • 16๋ฒ„์ „๊นŒ์ง€๋Š” document, 17๋ถ€ํ„ฐ๋Š” ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ์ตœ์ƒ๋‹จ ํŠธ๋ฆฌ(root element)
      • ์ ์ง„์  ์—…๊ทธ๋ ˆ์ด๋“œ ์ง€์›
        • ๋ชจ๋“  ์ด๋ฒคํŠธ๊ฐ€ docuemnet์— ์žˆ์Œ
        • ๋‹ค๋ฅธ ๋ฒ„์ „์˜ ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฃจํŠธ ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰์„ ์ˆ˜ ์—†๋‹ค
        • ๋”ฐ๋ผ์„œ ์ด๋ฒคํŠธ๋ฅผ ํ•ด๋‹น ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ์ˆ˜์ค€์œผ๋กœ ๊ฒฉ๋ฆฌํ•˜์—ฌ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ํ˜ผ์„ ์„ ๋ง‰์Œ
        • ์ ์ง„์  ์—…๊ทธ๋ ˆ์ด๋“œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ JQuery ๋“ฑ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋„ ํ†ต์šฉ๋จ
      • ๊ทธ๋ž˜์„œ ๋ฆฌ์•กํŠธ 16๋ฒ„์ „์—์„œ root element์— event stopPropagationํ•˜๋ฉด ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค~
  • document.addEventListener๋ฅผ ํ™œ์šฉํ•ด ๋ฆฌ์•กํŠธ์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ document์—์„œ ํ™•์ธํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค? > ์ด๋ฒคํŠธ๊ฐ€ document๊นŒ์ง€ ์ „ํŒŒ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์žˆ์Œ

JSX transfrom

  • JSX๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๊ฐ€ ์•„๋‹˜
    • ๋ฐ”๋ฒจ, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ
  • 16๊นŒ์ง€๋Š” JSX ๋ณ€ํ™˜์„ ์œ„ํ•ด 'react' import๊ฐ€ ํ•„์š”ํ–ˆ๊ณ , ์—†์œผ๋ฉด ์—๋Ÿฌ์˜€๋‹ค, react.createElement
  • 17๋ถ€ํ„ฐ๋Š” ๋ฐ”๋ฒจ๊ณผ ํ˜‘๋ ฅํ•ด ์ด๋Ÿฌํ•œ import ๊ตฌ๋ฌธ ์—†์ด๋„ JSX ๋ณ€ํ™˜, _jsxRuntime
    • import ์‚ญ์ œํ•˜๋‹ˆ๊นŒ ๋ฒˆ๋“ค๋ง ํฌ๊ธฐ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ์ค„์ž„
    • ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑ ๊ฐ„๊ฒฐํ™”. ๋‚ด๋ถ€ ๋กœ์ง๋˜ํ•œ ๊ฐ„๊ฒฐํ•˜๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฏ€๋กœ import React ์ง€์šฐ๊ณ , tsconfig.json์˜ jsx๋Š” "react-jsx"

event pooling ์ œ๊ฑฐ

  • ๋ฆฌ์•กํŠธ 16์˜ ์ด๋ฒคํŠธ ํ’€๋ง
    • SyntheticEvent ํ’€์„ ๋งŒ๋“ค์–ด์„œ, ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ€์ ธ์˜จ ๊ฒƒ์„ ์˜๋ฏธ
  • SyntheticEvent: ๋ธŒ๋ผ์šฐ์ €์˜ ๊ธฐ๋ณธ ์ด๋ฒคํŠธ๋ฅผ ํ•œ ๋ฒˆ ๋” ๊ฐ์‹ผ ์ด๋ฒคํŠธ ๊ฐ์ฒด
    • ํ•œ ๋ฒˆ ๋ž˜ํ•‘ํ•œ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์ด๋ฒคํŠธ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฏ€๋กœ -> ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์ž‘์—…
    • ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ๊ธฐ์ ์œผ๋กœ ํ•ด์ œํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€
  • ์ด๋ฒคํŠธ ํ’€๋ง ์‹œ์Šคํ…œ
    1. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ด
    2. ํ•ฉ์„ฑ ์ด๋ฒคํŠธ ํ’€์—์„œ ํ•ฉ์„ฑ ์ด๋ฒคํŠธ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ ธ์˜ด
    3. ์ด๋ฒคํŠธ ์ •๋ณด๋ฅผ ํ•ฉ์„ฑ ์ด๋ฒคํŠธ ๊ฐ์ฒด์— ๋„ฃ๋Š”๋‹ค
    4. ์œ ์ €๊ฐ€ ์ง€์ •ํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์‹คํ–‰
    5. ์ด๋ฒคํŠธ ๊ฐ์ฒด ์ดˆ๊ธฐํ™” => ๋‹ค์‹œ ์ด๋ฒคํŠธ ํ’€...
  • ์ด๋ฒคํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜์ž๋งˆ์ž ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐฉ์‹์€ ์ง๊ด€์ ์ด์ง€ ์•Š์•˜๋‹ค. ใ… ใ… 
  • ์ด๋ฒคํŠธ ํ’€๋ง ๋ฐฉ์‹์œผ๋กœ, ์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    • ์žฌ์‚ฌ์šฉ ์‚ฌ์ด์— ๋ชจ๋“  ์ด๋ฒคํŠธ ํ•„๋“œ๋ฅผ null๋กœ ๋ณ€๊ฒฝ(์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด ์ดˆ๊ธฐํ™”)
    • ์ดˆ๊ธฐํ™”๋œ ์ดํ›„์— e์— ์ ‘๊ทผํ•˜๋ฉด null
      • e.persist()๊ฐ™์€ ๋ณ„๋„ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค
  • ์ฆ‰, ๋ณ„๋„ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ํ•ฉ์„ฑ ์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•œ๋‹ค. ์„ฑ๋Šฅ ํ–ฅ์ƒ์— ๋„์›€์ด ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ event pooling ๊ฐœ๋…์ด ์‚ญ์ œ๋˜์—ˆ๋‹ค. ๋˜ํ•œ ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ € ์„ฑ๋Šฅ์ด ๊ฐœ์„ ๋˜์–ด, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ์ด๋ฒคํŠธ ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ๋•Œ ๋น„๋™๊ธฐ๋“  ๋™๊ธฐ๋“  ์ƒ๊ด€์—†์Œ

useEffect ํด๋ฆฐ์—… ํ•จ์ˆ˜์˜ ๋น„๋™๊ธฐ ์‹คํ–‰

  • useEffect์˜ ํด๋ฆฐ์—… ํ•จ์ˆ˜๋Š” 16๋ฒ„์ „๊นŒ์ง€๋Š” ๋™๊ธฐ์˜€๋‹ค
    • ๋ถˆํ•„์š”ํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค
  • 17๋ถ€ํ„ฐ๋Š” ํ™”๋ฉด์ด ์™„์ „ํžˆ ์—…๋ฐ์ดํŠธ ๋œ ์ดํ›„์— ํด๋ฆฐ์—… ํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.
    • ํด๋ฆฐ์—… ํ•จ์ˆ˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ปค๋ฐ‹ ๋‹จ๊ณ„๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์ง€์—ฐ๋œ๋‹ค
    • "ํ™”๋ฉด์˜ ์—…๋ฐ์ดํŠธ๊ฐ€ ์™„์ „ํžˆ ๋๋‚œ ์ดํ›„"์— ์‹คํ–‰๋˜๋„๋ก ๋ฐ”๋€Œ์—ˆ์œผ๋ฉฐ, ์„ฑ๋Šฅ์  ์ด์ ์ด ๋˜์—ˆ๋‹ค
      • => Profiler๋กœ commitTime ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ

Profiler

https://react.dev/reference/react/Profiler
<Profiler> lets you measure rendering performance of a React tree programmatically.

<Profiler id="App" onRender={onRender}>
  <App />
</Profiler>
  • ์ฝ˜์†” ํ…Œ์ด๋ธ” ์ฐ์œผ๋ฉด์„œ ํผํฌ๋จผ์Šค ํ™•์ธ ๊ฐ€๋Šฅ << ์‹ ๊ธฐํ•จ

์ปดํฌ๋„ŒํŠธ์˜ undefined ๋ฐ˜ํ™˜์— ๋Œ€ํ•œ ์ผ๊ด€์  ์ฒ˜๋ฆฌ

| react | ์ผ€์ด์Šค | ์—๋Ÿฌ ์—ฌ๋ถ€ | | ------ | ---------------------------------------------------------------- | --------- | | 16, 17 | ์ปดํฌ๋„ŒํŠธ๊ฐ€ undefined๋ฅผ ๋ฐ˜ํ™˜ | O | | 16 | memo, forwardRef๊ฐ€ undefined๋ฅผ ๋ฐ˜ํ™˜ | X | | 17 | memo, forwardRef๊ฐ€ undefined๋ฅผ ๋ฐ˜ํ™˜ | O | | 18 | ์ปดํฌ๋„ŒํŠธ๊ฐ€ undefined๋ฅผ ๋ฐ˜ํ™˜, memo, forwardRef๊ฐ€ undefined๋ฅผ ๋ฐ˜ํ™˜ | X |

17.0.0 ๋” ์‚ดํŽด๋ณด๊ธฐ

  • https://github.com/facebook/react/releases/tag/v17.0.0
  • ๋ฆฌ์•กํŠธ 16 ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ๋‹ค๋ฉด 17๋กœ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค
    • ์ ์ง„์  ์—…๊ทธ๋ ˆ์ด๋“œ ๋Œ€๋น„
    • ๊ณต์ˆ˜๊ฐ€ ํฌ๊ธฐ ์•Š์Œ