개인 곡뢀λ₯Ό μœ„ν•΄ μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€

μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μœ„ν•œ μƒνƒœ 관리 라이브러리, λ¦¬λ•μŠ€πŸ‘ λ¦¬μ•‘νŠΈλ₯Ό μ‚¬μš©ν•˜λŠ” λ§Žμ€ ν”„λ‘œμ νŠΈμ—μ„œ λ¦¬λ•μŠ€λ„ 같이 μ‚¬μš©ν•˜λŠ”λ°, κ·Έ μ΄μœ λŠ”

  • μ»΄ν¬λ„ŒνŠΈ μ½”λ“œμ™€ μƒνƒœ 관리 μ½”λ“œμ˜ 뢄리가 κ°€λŠ₯ν•˜κ³ 
  • SSRμ‹œ 데이터 전달이 κ°„νŽΈν•˜λ‹€
  • λ¦¬μ•‘νŠΈ μ»¨ν…μŠ€νŠΈλ³΄λ‹€ 효율적인 λ Œλ”λ§μ΄ κ°€λŠ₯ν•˜λ‹€
  • 미듀웨어λ₯Ό ν™œμš©ν•œ λ‹€μ–‘ν•œ κΈ°λŠ₯ 좔가도 κ°€λŠ₯ν•˜λ‹€
    • κ°•λ ₯ν•œ 미듀웨어 라이브러리 (ex. redux-saga)
    • 둜컬 μŠ€ν† λ¦¬μ§€μ— 데이터 μ €μž₯ν•˜κ³  λΆˆλŸ¬μ˜€λŠ” μ½”λ“œλ₯Ό μ‰½κ²Œ μž‘μ„±ν•  수 μžˆλ‹€

이런 이유둜 κ³΅λΆ€ν•œ react-redux에 λŒ€ν•΄ 정리해본닀.


λ¦¬λ•μŠ€λ‘œ μƒνƒœ κ΄€λ¦¬ν•˜κΈ°

λ¦¬λ•μŠ€ μ‚¬μš© μ‹œ 따라야 ν•  μ„Έ 가지 원칙

1. 전체 μƒνƒœκ°’μ„ ν•˜λ‚˜μ˜ store 객체에 μ €μž₯ν•œλ‹€

전체 μƒνƒœκ°’μ΄ ν•˜λ‚˜μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ 객체둜 ν‘œν˜„λ˜κΈ° λ•Œλ¬Έμ— ν™œμš©λ„κ°€ 높아진닀. λ¦¬λ•μŠ€λ₯Ό μ‚¬μš©ν•˜λ©΄

  • ν•˜λ‚˜μ˜ 객체λ₯Ό 직렬화(serialize)ν•΄μ„œ μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈκ°€ ν”„λ‘œκ·Έλž¨ 전체 μƒνƒœκ°’μ„ μ„œλ‘œ μ£Όκ³  받을 수 있고
  • ν”„λ‘œκ·Έλž¨μ΄ νŠΉμ •ν•œ μƒνƒœμ— μžˆμ„ λ•Œ λ°œμƒν•˜λŠ” 버그λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄ κ·Έ μƒνƒœκ°’μ„ μ €μž₯ν•œ ν›„ λ°˜λ³΅ν•΄μ„œ μž¬ν˜„ν•  수 μžˆλ‹€
  • 졜근의 μƒνƒœκ°’μ„ 버리지 μ•Šκ³  μ €μž₯ν•΄ λ†“μœΌλ©΄ μ‹€ν–‰ μ·¨μ†Œ(undo)와 λ‹€μ‹œ μ‹€ν–‰(redo) κΈ°λŠ₯을 μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€


2. μƒνƒœκ°’μ€ λΆˆλ³€ 객체이닀

μƒνƒœκ°’μ€ 였직 μ•‘μ…˜ 객체에 μ˜ν•΄μ„œλ§Œ λ³€κ²½λ˜μ–΄μ•Ό ν•œλ‹€

const incrementAction = {
  type: "INCREMENT", // --------------(1)
  amount: 123, // --------------(2)
};

store.dispatch(incrementAction); // --(3)


incrementActionλΌλŠ” μ΄λ¦„μ˜ μ•‘μ…˜ 객체λ₯Ό μ‚΄νŽ΄λ³΄λ©΄, (1) μ•‘μ…˜ κ°μ²΄λŠ” type 속성값이 μ‘΄μž¬ν•΄μ•Ό ν•œλ‹€. type μ†μ„±κ°’μœΌλ‘œ μ•‘μ…˜ 객체λ₯Ό κ΅¬λΆ„ν•œλ‹€. (2) type 속성값을 μ œμ™Έν•˜λ©΄ λ‚˜λ¨Έμ§€λŠ” μƒνƒœκ°’μ„ μˆ˜μ •ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” 정보닀 (3) μ•‘μ…˜ 객체와 ν•¨κ»˜ dispatch λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ μƒνƒœκ°’μ΄ λ³€κ²½λœλ‹€.

λ¦¬λ•μŠ€μ˜ μƒνƒœκ°’μ„ μˆ˜μ •ν•˜λŠ” μœ μΌν•œ 방법은 μ•‘μ…˜ 객체와 dispatch λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 것이닀. λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ μƒνƒœκ°’μ„ μˆ˜μ •ν•˜λ©΄ μ•ˆ λœλ‹€.

μƒνƒœκ°’μ€ dispatch λ©”μ„œλ“œκ°€ 호좜된 μˆœμ„œλŒ€λ‘œ λ¦¬λ•μŠ€ λ‚΄λΆ€μ—μ„œ λ³€κ²½λœλ‹€

λΆˆλ³€ 객체λ₯Ό μ‚¬μš©ν•˜λŠ” μ΄μœ λŠ”, 이전 μƒνƒœκ°’κ³Ό 이후 μƒνƒœκ°’μ„ λΉ„κ΅ν•΄μ„œ λ³€κ²½ μ—¬λΆ€λ₯Ό νŒŒμ•…ν•  λ•Œ μœ λ¦¬ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. λΆˆλ³€ 객체λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  직접 μƒνƒœκ°’μ„ μˆ˜μ •ν•˜κ²Œ 되면 이전 μƒνƒœκ°’ 비ꡐ가 μ–΄λ ΅λ‹€.


3. μƒνƒœκ°’μ€ 순수 ν•¨μˆ˜μ— μ˜ν•΄μ„œλ§Œ λ³€κ²½λ˜μ–΄μ•Ό ν•œλ‹€

λ¦¬λ“€μ„œ(reducer): λ¦¬λ•μŠ€μ—μ„œ μƒνƒœκ°’μ„ λ³€κ²½ν•˜λŠ” ν•¨μˆ˜ (state, action) => nextState

λ¦¬λ“€μ„œλŠ” 이전 μƒνƒœκ°’κ³Ό μ•‘μ…˜ 객체λ₯Ό μž…λ ₯λ°›μ•„ μƒˆλ‘œμš΄ μƒνƒœκ°’μ„ λ§Œλ“œλŠ” 순수 ν•¨μˆ˜μ΄λ‹€.

순수 ν•¨μˆ˜λŠ”

  • side effect(μ „μ—­ λ³€μˆ˜μ˜ 값을 μˆ˜μ •ν•˜κ±°λ‚˜ API μš”μ²­μ„ λ³΄λ‚΄λŠ” λ“± ν•¨μˆ˜ μ™ΈλΆ€μ˜ μƒνƒœλ₯Ό λ³€κ²½μ‹œν‚€λŠ” 것)λ₯Ό λ°œμƒμ‹œν‚€μ§€ μ•Šμ•„μ•Ό ν•˜κ³ ,
  • 같은 μΈμˆ˜μ— λŒ€ν•΄ 항상 같은 값을 λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.
    • 랜덀 ν•¨μˆ˜λ‚˜ μ‹œκ°„ ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜λ©΄ 순수 ν•¨μˆ˜κ°€ μ•„λ‹ˆλ‹€.
    • 같은 인수λ₯Ό μž…λ ₯해도 ν˜ΈμΆœν•˜λŠ” μ‹œμ μ— 따라 λ‹€λ₯Έ 값을 λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

μ΄λŸ¬ν•œ νŠΉμ„± 덕뢄에 순수 ν•¨μˆ˜λŠ” ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κΈ° 쉽닀.



λ¦¬λ•μŠ€μ˜ μ£Όμš” κ°œλ…

  • μƒνƒœκ°’μ΄ λ³€κ²½λ˜λŠ” κ³Όμ •

λ·°(μ»΄ν¬λ„ŒνŠΈ)κ°€ μƒνƒœκ°’μ„ λ³€κ²½ν•˜κ³  싢을 λ•ŒλŠ” μ•‘μ…˜μ„ λ°œμƒμ‹œν‚¨λ‹€. μ•‘μ…˜μ€ 미듀웨어가 μ²˜λ¦¬ν•˜κ³  (미듀웨어에 μ›ν•˜λŠ” κΈ°λŠ₯ 좔가도 κ°€λŠ₯ν•˜λ‹€) λ¦¬λ“€μ„œλŠ” μ•‘μ…˜μ— μ˜ν•΄μ„œ μƒνƒœκ°’μ΄ μ–΄λ–»κ²Œ λ³€κ²½λ˜λŠ”μ§€ λ‘œμ§μ„ λ‹΄κ³  μžˆλ‹€. λ¦¬λ“€μ„œλŠ” μƒˆλ‘œμ€ μƒνƒœκ°’μ„ 좜λ ₯ν•˜λŠ”λ°, κ·Έ μƒˆλ‘œμš΄ μƒνƒœκ°’μ„ μŠ€ν† μ–΄μ—κ²Œ μ•Œλ €μ£Όλ©΄ μŠ€ν† μ–΄λŠ” μƒνƒœκ°’μ„ μ €μž₯ν•œλ‹€. λ³€κ²½λœ μƒνƒœκ°’μ„ λ‹€μ‹œ λ·°μ—κ²Œ μ•Œλ €μ€€λ‹€.


🌈 μƒνƒœκ°’μ„ λ³€κ²½ν•˜λŠ” κ³Όμ •μ—μ„œ 거치게 λ˜λŠ” 4가지 μš”μ†Œ

  • 🚩 μ•‘μ…˜
    • dispatchλŠ” μ•‘μ…˜μ΄ λ°œμƒν–ˆλ‹€λŠ” 것을 λ¦¬λ•μŠ€μ—κ²Œ μ•Œλ €μ£ΌλŠ” ν•¨μˆ˜
    • (2) action creatorλ₯Ό λ§Œλ“€μ–΄μ„œ μ‚¬μš©ν•˜λŠ” μ΄μœ λŠ”, 각 μ•‘μ…˜ 객체의 ꡬ쑰λ₯Ό 일관성 있게 μž‘μ„±ν•˜κΈ° μœ„ν•¨
    • (3) μ•‘μ…˜ type을 μƒμˆ˜ λ³€μˆ˜λ‘œ κ΄€λ¦¬ν•˜λŠ” μ΄μœ λŠ”,
      • action creator μ—μ„œλ„ μ‚¬μš©ν•˜μ§€λ§Œ
      • reducer μ—μ„œλ„ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έ
// (1) dispatch()λ₯Ό ν˜ΈμΆœν•  λ•Œ μ•‘μ…˜ 객체λ₯Ό 직접 μž…λ ₯ν•œ case
store.dispatch({
  type: 'todo/ADD'  // type: μ•‘μ…˜μ„ κ΅¬λΆ„ν•˜λŠ” μ†μ„±κ°’μ΄λ―€λ‘œ κ³ μœ ν•΄μ•Ό ν•œλ‹€.
  title: 'λ¦¬λ•μŠ€ κ³΅λΆ€ν•˜κΈ°'
});

// (2) action creator ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄μ„œ ν˜ΈμΆœν•œ case
const ADD = 'todo/ADD' // (3) μ•‘μ…˜ type을 μƒμˆ˜ λ³€μˆ˜λ‘œ 관리

function addTodo(title) {
  return { type: ADD, title }
}

store.dispatch(addTodo({ title: 'λ¦¬λ•μŠ€ κ³΅λΆ€ν•˜κΈ°' }))


  • 🚩 미듀웨어

    미듀웨어(middleware)λŠ” λ¦¬λ“€μ„œκ°€ μ•‘μ…˜μ„ μ²˜λ¦¬ν•˜κΈ° 전에 μ‹€ν–‰ν•˜λŠ” ν•¨μˆ˜

    • λ―Έλ“€μ›¨μ–΄μ˜ κΈ°λ³Έ ꡬ쑰
      • ν•¨μˆ˜ μ„Έ κ°œκ°€ μ€‘μ²©λœ ꡬ쑰둜 λ˜μ–΄μžˆλ‹€.
// λ―Έλ“€μ›¨μ–΄μ˜ κΈ°λ³Έ ꡬ쑰: ν™”μ‚΄ν‘œ μ‚¬μš©
const myMiddleware = (store) => (next) => (action) => next(action);

// λ―Έλ“€μ›¨μ–΄μ˜ κΈ°λ³Έ ꡬ쑰: ν™”μ‚΄ν‘œ μ‚¬μš©X
const myMiddleware = function (store) {
  return function (next) {
    return function (action) {
      return next(action);
    };
  };
};


🌱 미듀웨어 μž‘μ„± 예제

const middleware1 = (store) => (next) => (action) => {
  console.log("middleware1 start"); // (2)
  const result = next(action); // (3)
  console.log("middleware1 end"); // (8)
  return result;
};

const middleware2 = (store) => (next) => (action) => {
  console.log("middleware2 start"); // (4)
  const result = next(action); // (5)
  console.log("middleware2 end"); // (7)
  return result;
};

const myReducer = (state, action) => {
  console.log("myReducer"); // (6)
  return state;
};

const store = createStore(myReducer, applyMiddleware(middleware1, middleware2));
store.dispatch({ type: "someAction" }); // (1)


(1) μ•‘μ…˜μ΄ λ°œμƒν–ˆμ„ λ•Œ 미듀웨어뢀터 μ²˜λ¦¬κ°€ λœλ‹€. 첫 번째 미듀웨어 middleware1κ°€ μ‹€ν–‰λ˜κ³  (2)κ°€ 좜λ ₯λœλ‹€. κ·Έ λ‹€μŒ μ€„μ˜ (3)nextλ₯Ό ν˜ΈμΆœν–ˆμ„ λ•Œ (4)이 좜λ ₯λœλ‹€. (3)nextλŠ” middleware2λ₯Ό μ˜λ―Έν•œλ‹€. (5)nextλŠ” μ—†κΈ° λ•Œλ¬Έμ— (5)nextλŠ” reducerλ₯Ό ν˜ΈμΆœν•œλ‹€. κ·Έλž˜μ„œ (6)λ₯Ό 좜λ ₯ν•˜κ²Œ 되고 (5)next인 myReducer()κ°€ μ’…λ£Œλ˜λ©΄μ„œ (7)이 좜λ ₯되고 (8)이 좜λ ₯λœλ‹€.

즉, λ―Έλ“€μ›¨μ–΄μ˜ μˆœμ„œλŒ€λ‘œ 호좜되고 nextλ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ λ‹€μŒ 미듀웨어λ₯Ό ν˜ΈμΆœν•˜κ²Œ 되고 λ§ˆμ§€λ§‰ λ―Έλ“€μ›¨μ–΄μ—μ„œλŠ” λ¦¬λ“€μ„œλ₯Ό ν˜ΈμΆœν•œλ‹€.

μƒνƒœκ°’ 변경을 κ²€μ‚¬ν•˜λŠ” μ½”λ“œλŠ” 각 이벀트 처리 ν•¨μˆ˜μ—μ„œ κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ”λ°, react-redux νŒ¨ν‚€μ§€μ˜ connectν•¨μˆ˜μ—μ„œλŠ” 자체적으둜 μƒνƒœκ°’ 변경을 κ²€μ‚¬ν•œλ‹€.

  • 🚩 λ¦¬λ“€μ„œ

    λ¦¬λ“€μ„œ(reducer)λŠ” μ•‘μ…˜μ— λ°œμƒν–ˆμ„ λ•Œ μƒˆλ‘œμš΄ μƒνƒœκ°’μ„ λ§Œλ“œλŠ” ν•¨μˆ˜λ‹€

    • λ¦¬λ“€μ„œμ˜ κΈ°λ³Έ ꡬ쑰
(state, action) => nextState;


🌱 λ¦¬λ“€μ„œ μž‘μ„± 예제

function reducer(state = INITIAL_STATE, action) { // (1) state = INITIAL_STATE
  switch (action.type){ // (2) μ•‘μ…˜ νƒ€μž…λ³„ case둜 처리
    case REMOVE_ALL :
      return { ...state, todos: [] } // (3) λΆˆλ³€ 객체둜 관리
    case REMOVE :
      return { ...state, todos state.todos.filter(todo => todo.id !== action.id) }
    default :
      return state; // (4)
  }
}

const INITIAL_STATE = { todos: [] }


λ¦¬λ•μŠ€λŠ” μŠ€ν† μ–΄λ₯Ό ν˜ΈμΆœν•  λ•Œ μƒνƒœκ°’μ΄ μ—†λŠ” μƒνƒœλ‘œ λ¦¬λ“€μ„œλ₯Ό ν˜ΈμΆœν•˜λ―€λ‘œ (1) λ§€κ°œλ³€μˆ˜μ˜ 기본값을 μ‚¬μš©ν•΄μ„œ 초기 μƒνƒœκ°’μ„ μ •μ˜ν•œλ‹€. (2) 각 μ•‘μ…˜ νƒ€μž…λ³„λ‘œ switch case문을 λ§Œλ“€μ–΄μ„œ μ²˜λ¦¬ν•œλ‹€. (3) μƒνƒœκ°’μ€ λΆˆλ³€ 객체둜 관리해야 ν•˜λ―€λ‘œ μˆ˜μ •ν•  λ•Œ λ§ˆλ‹€ μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν•œλ‹€. (4) μ²˜λ¦¬ν•  μ•‘μ…˜μ΄ μ—†λ‹€λ©΄ μƒνƒœκ°’μ„ λ³€κ²½ν•˜μ§€ μ•ŠλŠ”λ‹€.

λΆˆλ³€ 객체λ₯Ό 관리할 λͺ©μ μœΌλ‘œ 이머(immer) νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•œλ‹€

🌱 이머(immer)λ₯Ό μ‚¬μš©ν•΄μ„œ λΆˆλ³€ 객체λ₯Ό κ΄€λ¦¬ν•˜λŠ” 예제

import produce from "immer";

const person = { name: "yurim", age: 20 };
const newPerson = produce(person, (draft) => {
  // (1)
  draft.age = 30;
});


(1) produce()의 첫 번째 μΈμžλŠ” λ³€κ²½ν•˜κ³ μž ν•˜λŠ” 객체, 두 번째 μΈμžλŠ” 첫 번째 인자둜 받은 객체λ₯Ό μˆ˜μ •ν•˜λŠ” ν•¨μˆ˜ draft 객체λ₯Ό μˆ˜μ •ν•˜λ©΄ produce()κ°€ μƒˆλ‘œμš΄ 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.

🌱 이머(immer)λ₯Ό μ‚¬μš©ν•΄μ„œ 예제 μ½”λ“œ λ¦¬νŽ™ν† λ§ ν•˜κΈ°

function reducer(state = INITIAL_STATE, action) {
  return produce(state, draft => {
    switch (action.type){
      case ADD :
        return { draft.todos.push(action.todo) } // (1)
      case REMOVE_ALL :
        return { draft.todos = [] }
      case REMOVE :
        return { draft.todos = draft.todos.filter(todo => todo.id !== action.id) }
      default :
        return state;
    }
  })
}

const INITIAL_STATE = { todos: [] }


(1) draftκ°€ μƒˆλ‘œμš΄ 객체λ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ, pushλ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•΄λ„ κΈ°μ‘΄ μƒνƒœκ°’μ€ 직접 μˆ˜μ •λ˜μ§€ μ•ŠλŠ”λ‹€.

🌱 createReducer()둜 λ¦¬λ“€μ„œ μž‘μ„±ν•˜κΈ° switchλ¬Έ 보닀 더 κ°„κ²°ν•˜κ²Œ λ¦¬λ“€μ„œ ν•¨μˆ˜λ₯Ό μž‘μ„±ν•  수 μžˆλ‹€

function reducer(state = INITIAL_STATE, { // (1)
  [ADD]: (state, action) => state.todos.push(action.todo),
  [REMOVE_ALL]: state => ( state.todos = [] ),
  [REMOVE]: (state, action) => (state.todos = state.todos.filter(todo => todo.id !== action.id))
})


첫 번째 인자둜 μ΄ˆκΈ°κ°’μ„ λ°›κ³ , (1) 두 번째 인자둜 μ•‘μ…˜ 처리 ν•¨μˆ˜λ₯Ό λ‹΄κ³  μžˆλŠ” 객체λ₯Ό λ°›λŠ”λ‹€.

  • 🚩 μŠ€ν† μ–΄

    μŠ€ν† μ–΄(store)λŠ” λ¦¬λ•μŠ€μ˜ μƒνƒœκ°’μ„ κ°€μ§€λŠ” 객체. μ•‘μ…˜μ˜ λ°œμƒμ€ μŠ€ν† μ–΄μ˜ dispatch()둜 μ‹œμž‘λœλ‹€

  • λ¦¬λ•μŠ€μ˜ 첫 번째 원칙에 따라 전체 μƒνƒœκ°’μ„ ν•˜λ‚˜μ˜ store 객체에 μ €μž₯ν•œλ‹€.
  • ν•˜μ§€λ§Œ μ—¬λŸ¬κ°œμ˜ store 객체λ₯Ό μ‚¬μš©ν•΄λ„ λ¬Έμ œκ°€ λ˜μ§€ μ•ŠλŠ”λ‹€.
  • λ‹¨μˆœνžˆ 데이터 μ’…λ₯˜μ— 따라 κ΅¬λΆ„ν•˜κΈ° μœ„ν•œ μš©λ„λΌλ©΄ combineReducer()λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.
  • νŠΉλ³„ν•œ μ΄μœ κ°€ μ—†λ‹€λ©΄ μŠ€ν† μ–΄λŠ” ν•˜λ‚˜λ§Œ λ§Œλ“œλŠ” 게 μ’‹λ‹€.



✨ tl;dr

λ¦¬λ•μŠ€λŠ”

  • 전체 μƒνƒœκ°’μ„ ν•˜λ‚˜μ˜ store 객체에 μ €μž₯ν•œλ‹€.
  • μ•‘μ…˜ 객체둜 μƒνƒœκ°’ 변경이 κ°€λŠ₯ν•œλ°,
    • μ•‘μ…˜ κ°μ²΄λŠ” typeμ†μ„±κ°’μœΌλ‘œ μ•‘μ…˜ 객체λ₯Ό κ΅¬λΆ„ν•œλ‹€.
    • μ•‘μ…˜ 객체와 ν•¨κ»˜ dispatch λ©”μ„œλ“œλ‘œ μƒνƒœκ°’μ„ λ³€κ²½ν•œλ‹€
  • λ―Έλ“€μ›¨μ–΄λŠ” λ¦¬λ“€μ„œκ°€ μ•‘μ…˜μ„ μ²˜λ¦¬ν•˜κΈ° 전에 μ‹€ν–‰ν•˜λŠ” ν•¨μˆ˜λ‹€.
    • 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” 쀑간 κ³Όμ •μ—μ„œ λ‘œμ§μ„ λ„£μ–΄μ„œ ν•„μš”ν•œ κΈ°λŠ₯을 μΆ”κ°€ν•  수 μžˆλ‹€ (ex. redux-saga)
      • 디버깅 λͺ©μ μœΌλ‘œ μƒνƒœκ°’ λ³€κ²½ μ‹œ 둜그λ₯Ό 좜λ ₯ν•˜κ±°λ‚˜
      • λ¦¬λ“€μ„œμ—μ„œ λ°œμƒν•œ μ˜ˆμ™Έλ₯Ό μ„œλ²„λ‘œ μ „μ†‘ν•˜λŠ” λ“±μ˜ λͺ©μ μœΌλ‘œ 미듀웨어가 ν™œμš©λœλ‹€.
  • λ¦¬λ“€μ„œλŠ” μ•‘μ…˜μ΄ λ°œμƒν–ˆμ„ λ•Œ μƒˆλ‘œμš΄ μƒνƒœκ°’μ„ λ§Œλ“œλŠ” ν•¨μˆ˜.
    • λ¦¬λ•μŠ€μ˜ μƒνƒœκ°’μ„ μˆ˜μ •ν•˜λŠ” μœ μΌν•œ 방법은
      • μ•‘μ…˜ 객체와 dispatch λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 것이닀.
    • λΆˆλ³€ 객체λ₯Ό 관리할 λͺ©μ μœΌλ‘œ 이머(immer) νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•œλ‹€
    • λ¦¬λ“€μ„œ μž‘μ„± μ‹œ μ£Όμ˜ν•  점
      • 데이터 μ°Έμ‘°: λ¦¬λ•μŠ€μ˜ μƒνƒœκ°’μ€ λΆˆλ³€ 객체이기 λ•Œλ¬Έμ— μ–Έμ œλ“ μ§€ 객체의 참쑰값이 변경될 수 μžˆμœΌλ―€λ‘œ 객체λ₯Ό μ°Έμ‘°ν•  λ•ŒλŠ” κ³ μœ ν•œ ID값을 μ΄μš©ν•˜λŠ”κ²Œ μ’‹λ‹€
      • 순수 ν•¨μˆ˜: λžœλ€ν•¨μˆ˜, μ‹œκ°„ν•¨μˆ˜ λ“± ν˜ΈμΆœν•˜λŠ” μ‹œμ μ— 따라 λ‹€λ₯Έ 값이 λ°˜ν™˜λ  수 μžˆμœΌλ―€λ‘œ μ‚¬μš©ν•˜λ©΄ μ•ˆ λœλ‹€.
  • μŠ€ν† μ–΄λŠ” λ¦¬λ•μŠ€μ˜ μƒνƒœκ°’μ„ κ°€μ§€λŠ” 객체. μ•‘μ…˜μ˜ λ°œμƒμ€ μŠ€ν† μ–΄μ˜ dispatch()둜 μ‹œμž‘λœλ‹€
  • λ¦¬λ•μŠ€λŠ” 단방ν–₯ 데이터 νλ¦„μ˜ νŠΉμ„±μ„ μ§€λ‹ˆκΈ° λ•Œλ¬Έμ— μƒλ‹Ήνžˆ 직관적이고 예츑 κ°€λŠ₯ν•˜λ‹€λŠ” μž₯점이 μžˆλ‹€. (κ°„λ‹¨ν•˜κ³  직관적인 ꡬ쑰)