๐ŸŽ„ ์„ฑ์žฅ์ผ์ง€ 3.0

์ฑ… ํ–‰๋ณตํ•œ ์ด๊ธฐ์ฃผ์˜์ž(์›จ์ธ ๋‹ค์ด์–ด)์˜ ๋‚ด์šฉ์— ์ž๊ทน๋ฐ›์•„ ์‹œ์ž‘ํ•˜๋Š” ์†Œ๋ฐ•ํ•œ ์„ฑ์žฅ๊ธฐ๋ก

์‚ด์•„์žˆ๋Š” ๊ฝƒ๊ณผ ์ฃฝ์€ ๊ฝƒ์€ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ณ„ํ•˜๋Š”๊ฐ€?
์„ฑ์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์‚ด์•„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
์ƒ๋ช…์˜ ์œ ์ผํ•œ ์ฆ๊ฑฐ๋Š” ์„ฑ์žฅ์ด๋‹ค!

๐ŸŒณ ํ‚ค์›Œ๋“œ (1.0)
์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌ, ์ถ”ํ›„์— ๋ณด๋ฉด์„œ ์Šค์Šค๋กœ ์„ค๋ช…
๐Ÿ‰ ๊ฒฝํ—˜ ์œ„์ฃผ๋กœ (2.0)
๋‹จ์ˆœ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ๋ณด๋‹ค ๋ฌด์—‡์„ ๋ฐฐ์› ๊ณ  ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€ ์งง๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑ
โ„๏ธ ์ •ํ•ด์ง„ ํ…œํ”Œ๋ฆฟ์— ๋งž์ถฐ์„œ (3.0)
ํ‚ค์›Œ๋“œ, ๊ฒฝํ—˜ ๋ชจ๋‘ ์ข‹๋‹ค. ๋‹ค๋งŒ ๋งค์ผ ์ž‘์„ฑํ•˜๊ธฐ๋กœ ๋งˆ์Œ ๋จน์€๋งŒํผ ํ•ต์‹ฌ๋งŒ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ…œํ”Œ๋ฆฟ์„ ์ž‘์„ฑ

๐Ÿ”‘ ์˜ค๋Š˜์˜ ํ‚ค์›Œ๋“œ

  • ๋ฆฌ์•กํŠธ
    • useReducer
      • ๋ฆฌ๋•์Šค์˜ reducer๋ฅผ ๋ฆฌ์•กํŠธ์—์„œ ๊ตฌํ˜„ํ•œ ํ›…์Šค
      • ๊ด€๋ฆฌํ•  state, setState๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์ง€๊ฒŒ ๋  ๋•Œ, ์ด๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ•˜๋‚˜์˜ state ๊ฐ์ฒด๋กœ ๊ด€๋ฆฌํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.(์•ฝ๊ฐ„ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ state๋ฅผ ๋‹ฎ์•˜๋‹ค.)
      • state๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ dispatch(setState ๋Š๋‚Œ)๋กœ ๋ณ€๊ฒฝํ•˜๊ณ , ์ด ๋•Œ dispatch๊ฐ€ action๊ฐ์ฒด๋ฅผ ๋„˜๊ธฐ๋ฉด, reducer ํ•จ์ˆ˜์—์„œ action๊ฐ์ฒด์˜ type์— ๋”ฐ๋ผ ๋ถ„๊ธฐ์ฒ˜๋ฆฌํ•˜์—ฌ state๋ฅผ ๋ณ€๊ฒฝ, ์กฐ์ž‘ํ•œ๋‹ค.
      • ์ข€๋” ์œ ๊ธฐ์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋Š๋‚Œ์ด๋‹ค. ๋‹จ, state๊ฐ€ ์—ฌ๋Ÿฌ ์ค‘์ฒฉ๋œ ๊ฐ์ฒด๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์ฝ”๋“œ๊ฐ€ ์กฐ๊ธˆ ๋“œ๋Ÿฌ๋ฒ„์ง„๋‹ค.(๋ถˆ๋ณ€์„ฑ ์œ ์ง€๋ฅผ ์œ„ํ•ด ๊ณ„์† ์–•์€ ๋ณต์‚ฌํ•จ) -> ์ด๊ฑธ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด immer ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ
      • ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด useReducer(reducer ๊ธฐ๋Šฅ)์™€ Context API(props drilling ํ•ด๊ฒฐ)์ด๋ฉด ๊ตณ์ด redux๋ฅผ ์“ธ ์ด์œ ๊ฐ€ ์—†์ง€ ์•Š๋‚˜? ์‹ถ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์‹ค์ œ ๋น„๋™๊ธฐ ์ƒํƒœ๊นŒ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ๋”์šฑ ํฐ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ฆฌ๋•์Šค๋ฅผ ์“ฐ๊ฒŒ ๋œ๋‹ค.(๊ทผ๋ฐ ์‚ฌ์‹ค ์š”์ฆ˜์—” ๋˜ ์„œ๋ฒ„ ์ƒํƒœ๋Š” react-query๋กœ ๊ด€๋ฆฌํ•˜๋Š” ์ถ”์„ธ)
    • ์ตœ์ ํ™” ํŒ
      • ๊ฐ ์ปดํฌ๋„ŒํŠธ์— console.log๋ฅผ ์ฐ์–ด์„œ ๋ Œ๋”๋ง ํ™•์ธ
      • useEffect, useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ค props๊ฐ€ ๋ Œ๋”๋ง ์‹œ ๋ณ€ํ•˜๋Š”์ง€ ์ฒดํฌํ•˜๋Š” ๋ฐฉ๋ฒ•
      • ๊ธฐ๋ณธ์ ์œผ๋กœ React.memo๋ฅผ ํ†ตํ•ด ์ตœ์ ํ™”(์“ธ๋ฐ์—†์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ์‹œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ ๋ง‰๊ธฐ)
      • ์ตœํ›„ ์ˆ˜๋‹จ์œผ๋กœ useMemo ํ›…์Šค๋ฅผ returnํ•˜๋Š” JSX ํ˜•ํƒœ์˜ ์ปดํฌ๋„ŒํŠธ์—๋„ ์”Œ์šธ ์ˆ˜ ์žˆ๋‹ค.(๊ฒฐ๊ตญ JSX ์ปดํฌ๋„ŒํŠธ๋„ ๊ฐ’์ด๋‹ˆ๊นŒ)

๐Ÿ“ ์š”์•ฝ ๋ฐ ํ•˜๋ฃจ ๊ฐ„๋‹จ ํšŒ๊ณ 

์ฒ˜์Œ์—” ์ง„์งœ ๋‚ฏ์„ค๊ณ  ํ—ท๊ฐˆ๋ ธ๋‹ค. reducer๋ผ๋Š” ๊ฐœ๋…์ด ๋ญ”์ง€๋„ ๋ชจ๋ฅด๊ฒ ๊ณ , dispatch/action์€ ๋˜ ๋ญ”์ง€โ€ฆ ๊ทธ๋ฆฌ๊ณ  ์ž˜ ์‚ฌ์šฉํ•˜์ง€๋„ ์•Š์•˜๋˜ switch๋„ ๋‚˜์˜ค๊ณ ..! ํ—Œ๋ฐ ๊ณ„์† ๊ณต๋ถ€ํ•˜๊ณ  ์‚ฌ์šฉํ•ด๋ณด๋‹ˆ, ๊ธˆ๋ฐฉ ์ต์ˆ™ํ•ด์กŒ๋‹ค. useReducer๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋Š๋‚€ ๊ฑด, ๋ญ”๊ฐ€ ๊ทธ state๋“ค์„ ์œ ๊ธฐ์ ์œผ๋กœ ์—ฎ์–ด์„œ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฑด ์•Œ๊ฒ ๋Š”๋ฐ ๋ญ”๊ฐ€ ์•„์ฃผ ์†์‹œ์›ํ•˜๊ฒŒ ํ•ด๊ฒฐ๋˜์ง€๋Š” ์•Š๋Š” ๊ธฐ๋ถ„..?์ด์—ˆ๋‹ค. ๊ฒฐ๊ตญ์—” dispatch๋„ ์ž์‹์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด props๋กœ ๊ณ„์† ์ „๋‹ฌํ•ด์ค˜์•ผํ•˜๊ณ  ์—ฌ๋Ÿฌ state๋“ค์— ๋Œ€ํ•ด์„œ ์ง€์ €๋ถ„ํ•˜๊ฒŒ setState๋ฅผ ์•ˆํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์•˜์ง€๋งŒ, ๊ทธ๋งŒํผ useReducer ์‚ฌ์šฉ๋ฐฉ๋ฒ•์ด ๋ณต์žกํ•˜๊ธฐ์— ํ‰์ณ์ง€๋Š” ๋Š๋‚Œ. ๊ทธ๋ž˜๋„ ์†์— ์ต์œผ๋‹ˆ๊นŒ ํ›จ์”ฌ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด๋ณด์ด๊ณ  ๊น”๋”ํ•ด๋ณด์ด๋Š” ๊ฑด ์‚ฌ์‹ค์ด๋‹ค.

์˜ˆ์ œ

import React, { useReducer } from 'react';

const initialState = {
  name: '',
  count: 0,
  favorites: [],
};

const SET_NAME = 'SET_NAME';
const reducer = (state, action) => {
  switch (action.type) {
    case SET_NAME:
      return {
        ...state,
        name: action.name,
      };
    default:
      return state;
  }
};

const Practice = () => {
  const [state, dispatch] = useReducer(reducer, initialState);

  const onClick = () => {
    dispatch({ type: SET_NAME, name: 'jay' });
  };

  return (
    <>
      <h1>{state.name}</h1>
      <button onClick={onClick}>ํด๋ฆญ!</button>
    </>
  );
};

export default Practice;