2024-03-13.md

🏑

DIL: λͺ¨λ˜ λ¦¬μ•‘νŠΈ λ”₯ λ‹€μ΄λΈŒ, 2μ£Όμ°¨-3

μŠ€ν„°λ””: μ›”κ°„ CS, https://github.com/monthly-cs/2024-03-modern-react-deep-dive
였늘 진행: κ°œμΈκ³΅λΆ€


DIL-week2-3_2024-03-13

| DIL μ£Όμ°¨ | λ²”μœ„ | λ‚΄μš© | 였늘차 진도 | | -------- | ------ | ------------------------------- | ----------- | | 2μ£Όμ°¨ | 3, 5μž₯ | λ¦¬μ•‘νŠΈ ν›…κ³Ό μƒνƒœκ΄€λ¦¬ 라이브러리 | 208~219p |

였늘 읽은 λ‚΄μš©μ„ markdown으둜 κ°„λ‹¨νžˆ λ©”λͺ¨
읽은 μ‹œκ°„: 10μ‹œ~11μ‹œ 감기 이슈-2πŸ€•


React Hook νŒŒν—€μΉ˜κΈ°

useMemo

  • λŒ€ν‘œμ μΈ μ΅œμ ν™” ν›…~
  • 인수
    • (1) 첫 번째 인수: μ–΄λ– ν•œ 값을 λ°˜ν™˜ν•˜λŠ” 생성 ν•¨μˆ˜
    • (2) 두 번째 인수: μ˜μ‘΄μ„± λ°°μ—΄
  • λ™μž‘
    • λžœλ”λ§ μ‹œ (2)의 값이 λ³€κ²½λ˜μ§€ μ•Šμ•˜μœΌλ©΄ => (1)을 μž¬μ‹€ν–‰ ν•˜μ§€ μ•Šκ³ , 이전에 κΈ°μ–΅ν•΄λ‘” κ°’ λ°˜ν™˜
    • λžœλ”λ§ μ‹œ (2)의 값이 λ³€κ²½λ˜μ—ˆμœΌλ©΄ => (1)을 μ‹€ν–‰ν•œ ν›„ 값을 λ°˜ν™˜ν•˜κ³ , κ·Έ 값을 κΈ°μ–΅
      • μ»΄ν¬λ„ŒνŠΈλ„ κ°€λŠ₯(μ•ˆ 함)
        const MemoizedComponent = useMemo(
          () => <ExpensiveComponent value={value} />,
          [value]
        );
        

useCallback

| hook | memoize | | ----------- | ----------------------------- | | useMemo | λ°˜ν™˜ κ°’ == λ³€μˆ˜ | | useCallback | 인수둜 λ„˜κ²¨ 받은 콜백 == ν•¨μˆ˜ |

  • useCallback은 인수둜 λ„˜κ²¨λ°›μ€ 콜백 자체λ₯Ό κΈ°μ–΅
    • νŠΉμ • ν•¨μˆ˜λ₯Ό μƒˆλ‘œ λ§Œλ“€μ§€ μ•Šκ³  λ‹€μ‹œ μž¬μ‚¬μš©ν•œλ‹€
  • ν•¨μˆ˜μ˜ μž¬μƒμ„±μ„ 막아 λΆˆν•„μš”ν•œ λ¦¬μ†ŒμŠ€, λ˜λŠ” λ¦¬λžœλ”λ§μ„ λ°©μ§€ν•œλ‹€
export default function Hooks() {
  const [status1, setStatus1] = useState(false);
  const [status2, setStatus2] = useState(false);

  const toggle1 = () => {
    setStatus1(!status1);
  }; // μ»΄ν¬λ„ŒνŠΈλ₯Ό λžœλ”λ§ν•  λ•Œ, ν•¨μˆ˜λ₯Ό μž¬μƒμ„±ν•œλ‹€

  const toggle2 = useCallback(
    function togge2() {
      setStatus2(!status2);
    },
    [status2]
  ); // μ»΄ν¬λ„ŒνŠΈλ₯Ό λžœλ”λ§ν•  λ•Œ, μ˜μ‘΄μ„± λ°°μ—΄μ˜ 값이 λ³€ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ ν•¨μˆ˜λ₯Ό μž¬μƒμ„±ν•˜μ§€ μ•ŠλŠ”λ‹€

  const toggle3 = useMemo(
    // `useMemo`λ₯Ό μ‚¬μš©ν•˜μ—¬ κ³„μ‚°λœ 값을 λ©”λͺ¨μ΄μ œμ΄μ…˜ν•©λ‹ˆλ‹€.
    // 이 ν•¨μˆ˜λŠ” `status3` μƒνƒœμ˜ 변경을 톡해 μƒμ„±λœ μƒˆλ‘œμš΄ ν† κΈ€ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    // `status3`κ°€ 변경될 λ•Œλ§Œ 이 ν•¨μˆ˜λ₯Ό μž¬κ³„μ‚°ν•˜μ—¬, μ„±λŠ₯을 μ΅œμ ν™”ν•©λ‹ˆλ‹€.
    function toggle3() {
      // -> 콜백 ν•¨μˆ˜: ν•¨μˆ˜ 선언문을 λ°˜ν™˜ν•œλ‹€
      return function () {
        // -> ν•¨μˆ˜(값을 λ°˜ν™˜ν•œλ‹€)
        return setStatus3(!status3);
      };
    },
    [status3] // μ˜μ‘΄μ„± λ°°μ—΄: 이 λ°°μ—΄μ˜ 값이 λ³€κ²½λ˜λ©΄, `toggle3` ν•¨μˆ˜λ₯Ό μž¬κ³„μ‚°ν•©λ‹ˆλ‹€.
  );

  return (
    <section>
      <aside>
        <label>Hooks</label>
        {/* Hooks */}
        <ChildComponent
          name="non useCallback"
          value={status1}
          onChange={toggle1}
        />
        <ChildComponent name="useCallback" value={status2} onChange={toggle2} />
        <ChildComponent
          name="useMemo둜 κ΅¬ν˜„ν•œ useCallback"
          value={status3}
          onChange={toggle3}
        />
      </aside>
    </section>
  );
}

(팁) κΈ°λͺ… ν•¨μˆ˜λ₯Ό 콜백 ν•¨μˆ˜λ‘œ λ„˜κ²¨μ£Όλ©΄, 크둬 λ©”λͺ¨λ¦¬ νƒ­μ—μ„œ 디버깅을 μš©μ΄ν•˜κ²Œ ν•  수 μžˆλ‹€ (μ΄λ¦„μœΌλ‘œ μΆ”μ ν•˜κΈ°~)

useRef

https://react.dev/reference/react/useRef

  • ref.current 속성은 λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€(mutable). <-> μƒνƒœ(state)
    • κ·ΈλŸ¬λ‚˜, λ Œλ”λ§μ— μ‚¬μš©λ˜λŠ” 객체(예λ₯Ό λ“€μ–΄, μƒνƒœμ˜ 일뢀)λ₯Ό λ‹΄κ³  μžˆλ‹€λ©΄, ν•΄λ‹Ή 객체λ₯Ό 직접 λ³€κ²½x
  • ref.current 속성을 변경해도 ReactλŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό λ‹€μ‹œ λ Œλ”λ§x (refλŠ” λ‹¨μˆœν•œ JavaScript 객체이기 λ•Œλ¬Έμ—, ReactλŠ” μ—¬λŸ¬λΆ„μ΄ 이λ₯Ό λ³€κ²½ν–ˆμ„ λ•Œλ₯Ό μ•Œ 수 μ—†μŠ΅λ‹ˆλ‹€)
  • λ Œλ”λ§ λ™μ•ˆ ref.currentλ₯Ό μ½κ±°λ‚˜ 쓰지 λ§ˆμ„Έμš”. μ΄ˆκΈ°ν™”λ₯Ό μ œμ™Έν•˜κ³ λŠ” 이λ₯Ό ν”Όν•΄μ•Ό ν•©λ‹ˆλ‹€. μ΄λŠ” μ»΄ν¬λ„ŒνŠΈμ˜ λ™μž‘μ„ 예츑 λΆˆκ°€λŠ₯ν•˜κ²Œ λ§Œλ“­λ‹ˆλ‹€.
  • 엄격 λͺ¨λ“œ(Strict Mode)μ—μ„œ ReactλŠ” μš°μ—°νžˆ λ°œμƒν•  수 μžˆλŠ” λΆ€μˆ˜ 효과(side effects)λ₯Ό μ°ΎκΈ° μœ„ν•΄ μ»΄ν¬λ„ŒνŠΈ ν•¨μˆ˜λ₯Ό 두 번 ν˜ΈμΆœν•©λ‹ˆλ‹€. μ΄λŠ” 개발용 λ™μž‘μœΌλ‘œ, ν”„λ‘œλ•μ…˜μ—λŠ” 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 각 ref κ°μ²΄λŠ” 두 번 μƒμ„±λ˜μ§€λ§Œ, κ·Έ 쀑 ν•˜λ‚˜λŠ” λ²„λ €μ§‘λ‹ˆλ‹€. μ»΄ν¬λ„ŒνŠΈ ν•¨μˆ˜κ°€ μˆœμˆ˜ν•˜λ‹€λ©΄(κ·Έλž˜μ•Όλ§Œ ν•©λ‹ˆλ‹€), μ΄λŠ” λ™μž‘μ— 영ν–₯을 주지 μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€. => μ»΄ν¬λ„ŒνŠΈλŠ” μˆœμˆ˜ν•΄μ•Ό ν•œλ‹€!
  • μ™œ 써야함? μ™ΈλΆ€μ—μ„œ κ°’ μ„ μ–Έν•˜λŠ” κ±°λž‘ 뭐라 닀름?
  • μ™ΈλΆ€μ—μ„œ 값을 μ„ μ–Έν–ˆμ„ λ•Œ
    • μ»΄ν¬λ„ŒνŠΈκ°€ μ‹€ν–‰λ˜μ§€ μ•Šμ•„λ„, 값이 기본적으둜 λ©”λͺ¨λ¦¬μ— 쑴재
    • μ»΄ν¬λ„ŒνŠΈκ°€ μ—¬λŸ¬λ²ˆ μƒμ„±λœλ‹€λ©΄? 각 μ»΄ν¬λ„ŒνŠΈμ—μ„œ κ°€λ¦¬ν‚€λŠ” 값이 동일
  • DOM에 μ ‘κ·Ό
    • λžœλ”λ§ 되기 μ „ (returndmfh DOM이 λ°˜ν™˜λ˜κΈ° μ „): undefined
  • (예제) λžœλ”λ§ μ•ˆλ˜λŠ” 점을 ν™œμš©ν•΄ usePrevious 같은 μ»€μŠ€ν…€ 훅을 λ§Œλ“€ 수 있음
    • κ°œλ°œμžκ°€ μ›ν•˜λŠ” μ‹œμ μ˜ 값을 λžœλ”λ§μ— 영ν–₯을 λΌμΉ˜μ§€ μ•Šκ³  보관
function MyUseRef<T>(initValue: T) {
  return useMemo(() => ({ current: initValue }), []);
  // 두 번째 μ˜μ‘΄μ„± 배열이 λΉ„μ–΄μžˆμœΌλ―€λ‘œ [], λžœλ”λ§λ  λ•Œλ₯Ό μ œμ™Έν•˜κ³  λ°˜ν™˜κ°’μ„ μž¬κ³„μ‚° ν•˜μ§€ μ•Šμ„ 것
  // => 즉, λžœλ”λ§ μ‹œλ§ˆλ‹€ 같은 μ£Όμ†Œμ˜ 값을 가리킴 (λžœλ”λ§ λ‹Ήμ‹œμ˜ λ°˜ν™˜κ°’μ΄ λ©”λͺ¨λ˜μ–΄μžˆμŒ)
  // => 객체 λ‚΄λΆ€μ˜ 값을 변경해도 객체의 μ£Όμ†Œκ°€ λ°”λ€Œμ§€ μ•ŠμœΌλ―€λ‘œ, current의 valueλ₯Ό 찾을 수 μžˆλ‹€
}