Y J S

React ์ƒํƒœ ๊ด€๋ฆฌ ๊ธฐ์ดˆ: useState/useReducer/Context์™€ ์„œ๋ฒ„ ์ƒํƒœ ๊ตฌ๋ถ„

์ƒํƒœ๋Š” ์™œ/์–ด๋–ป๊ฒŒ ๋‚˜๋ˆŒ๊นŒ

  • ํด๋ผ์ด์–ธํŠธ(UI) ์ƒํƒœ: ์ž…๋ ฅ๊ฐ’, ๋ชจ๋‹ฌ ํ† ๊ธ€, ํƒญ ์„ ํƒ ๋“ฑ ์•ฑ ๋‚ด๋ถ€์—์„œ๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๊ฐ’
  • ์„œ๋ฒ„ ์ƒํƒœ: API์—์„œ ๊ฐ€์ ธ์˜จ ์›๊ฒฉ ๋ฐ์ดํ„ฐ(๊ณต์œ ยท์บ์‹œยท๋™๊ธฐํ™” ํ•„์š”)
  • ๊ถŒ์žฅ: UI๋Š” React ํ›…๊ณผ(ํ•„์š” ์‹œ ๊ฒฝ๋Ÿ‰ ์ „์—ญ ์ƒํƒœ), ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ๋Š” React Query/SWR ๊ฐ™์€ ๋„๊ตฌ ์‚ฌ์šฉ

useState: ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ณ  ๋น ๋ฅธ ๋กœ์ปฌ ์ƒํƒœ

  • ๋™๊ธฐ ๋ Œ๋”์ฒ˜๋Ÿผ ๋ณด์—ฌ๋„ ์—…๋ฐ์ดํŠธ๋Š” ๋ฐฐ์นญ๋จ. ๋™์ผ ์ด๋ฒคํŠธ ๋ฃจํ”„ ๋‚ด ๋‹ค์ค‘ setState๋Š” ํ•œ ๋ฒˆ์˜ ๋ Œ๋”๋กœ ํ•ฉ์ณ์ง
  • ์ด์ „ ๊ฐ’ ์˜์กด ์‹œ ํ•จ์ˆ˜ํ˜• ์—…๋ฐ์ดํŠธ ๊ถŒ์žฅ: setCount(c => c + 1)
import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);
  const inc = () => setCount((c) => c + 1);
  return <button onClick={inc}>count: {count}</button>;
}

useReducer: ์ „์ด(transition)๊ฐ€ ๋งŽ์€ ์ƒํƒœ์— ์ ํ•ฉ

  • ์•ก์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒํƒœ ์ „์ด๋ฅผ ๋ช…์‹œํ™”. ๋กœ์ง์„ ์ปดํฌ๋„ŒํŠธ ๋ฐ–์œผ๋กœ ๋ถ„๋ฆฌํ•ด ํ…Œ์ŠคํŠธ/๊ฐ€๋…์„ฑ ํ–ฅ์ƒ
type Action = { type: "inc" } | { type: "dec" } | { type: "reset" };
function reducer(state: number, action: Action) {
  switch (action.type) {
    case "inc":
      return state + 1;
    case "dec":
      return state - 1;
    case "reset":
      return 0;
  }
}

Context: ํŠธ๋ฆฌ ์ „๋ฐ˜์œผ๋กœ ๊ฐ’ ์ „๋‹ฌ(๋‚จ์šฉ ์ฃผ์˜)

  • ํ…Œ๋งˆ, ์ธ์ฆ ์‚ฌ์šฉ์ž ๊ฐ™์€ ๋นˆ๋„ ๋‚ฎ์€ ๋ณ€๊ฒฝ์— ์ ํ•ฉ
  • ์ž์ฃผ ๋ณ€ํ•˜๋Š” ๊ฐ’์€ ์ปจํ…์ŠคํŠธ๋ฅผ ์ชผ๊ฐœ๊ฑฐ๋‚˜ ์…€๋ ‰ํ„ฐ ํŒจํ„ด, ์ „์—ญ ์ƒํƒœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ณ ๋ ค

์ „์—ญ ์ƒํƒœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ ํƒ ๊ธฐ์ค€

  • Redux Toolkit: ๋ช…ํ™•ํ•œ ํŒจํ„ด/๋ฏธ๋“ค์›จ์–ดยทํˆด๋ง ๊ฐ•ํ•จ, ํŒ€ ํ˜‘์—…์— ์œ ๋ฆฌ
  • Zustand/Jotai: ๊ฐ€๋ณ๊ณ  ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ ์Œ, ์ž‘์€/์ค‘ํ˜• ์•ฑ์— ํšจ์œจ์ 
  • Recoil: ์˜์กด ๊ทธ๋ž˜ํ”„/ํŒŒ์ƒ ์ƒํƒœ ๊ด€๋ฆฌ ์šฉ์ด

useEffect๋Š” ์–ธ์ œ ์“ฐ๋‚˜

  • "๋ Œ๋” ๊ฒฐ๊ณผ๋ฅผ ์™ธ๋ถ€ ์„ธ๊ณ„์™€ ๋™๊ธฐํ™”"ํ•  ๋•Œ: ๊ตฌ๋…/ํƒ€์ด๋จธ/DOM API/ํฌ์ปค์Šค ๋“ฑ
  • ๋ฐ์ดํ„ฐ ํŒจ์นญ์€ ์„œ๋ฒ„ ์ƒํƒœ ๋„๊ตฌ(React Query ๋“ฑ)๋กœ ๋Œ€์ฒด ๊ณ ๋ ค
  • ์˜์กด์„ฑ ๋ฐฐ์—ด ์ •ํ™•ํžˆ ๊ด€๋ฆฌํ•˜๊ณ  ๋ถˆํ•„์š”ํ•œ ์ดํŽ™ํŠธ ์ œ๊ฑฐ

Ref vs State

  • useRef๋Š” ๊ฐ’์ด ๋ฐ”๋€Œ์–ด๋„ ๋ฆฌ๋ Œ๋”๋ฅผ ์ผ์œผํ‚ค์ง€ ์•Š์Œ(์ž„์‹œ ๊ฐ’, DOM ์ฐธ์กฐ)
  • useState๋Š” UI์— ๋ฐ˜์˜๋˜์–ด์•ผ ํ•˜๋Š” ๊ฐ’

์„ฑ๋Šฅ/๊ฒฝํ—˜ ํŒ

  • ๋ถˆ๋ณ€์„ฑ ์œ ์ง€๋กœ ์ฐธ์กฐ ๋™์ผ์„ฑ ๊ด€๋ฆฌ โ†’ ๋ถˆํ•„์š” ๋ฆฌ๋ Œ๋” ๊ฐ์†Œ
  • memo/useMemo/useCallback์€ ์ธก์ • ํ›„ ํ•„์š”ํ•œ ๊ณณ์—๋งŒ ์ ์šฉ
  • ์ž…๋ ฅ ์ง€์—ฐ/์šฐ์„ ์ˆœ์œ„ ์กฐ์ ˆ: useDeferredValue, useTransition
  • ๋ฆฌ์ŠคํŠธ ๋ Œ๋”๋Š” ์•ˆ์ •์ ์ธ key ์‚ฌ์šฉ(์ธ๋ฑ์Šค ์ง€์–‘)

์ฒดํฌ๋ฆฌ์ŠคํŠธ(์š”์•ฝ)

  • ์ด ๊ฐ’์€ ์„œ๋ฒ„์—์„œ ์˜ค๋‚˜? โ†’ ์„œ๋ฒ„ ์ƒํƒœ ๋„๊ตฌ๋กœ ๊ด€๋ฆฌ
  • ์ „์ด ๋ณต์žก/์•ก์…˜ ๋‹ค์ˆ˜? โ†’ useReducer
  • ํŠธ๋ฆฌ ์ „๋ฐ˜ ๊ณต์œ ? โ†’ Context(๋นˆ๋„ ๋‚ฎ์Œ) ๋˜๋Š” ์ „์—ญ ์ƒํƒœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ๋นˆ๋ฒˆํ•œ ๋ Œ๋”? โ†’ ํŒŒ์ƒ ๊ฐ’ ๋ฉ”๋ชจ, ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ, key ์•ˆ์ •์„ฑ ์ ๊ฒ€