Skip to content
Yancy edited this page Nov 24, 2020 · 9 revisions

λ¦¬λ•μŠ€

μž₯점

  • μ»΄ν¬λ„ŒνŠΈ μ½”λ“œλ‘œ λΆ€ν„° μƒνƒœ 관리 μ½”λ“œλ₯Ό 뢄리할 수 μžˆλ‹€.
  • μ„œλ²„ λ Œλ”λ§ μ‹œ 데이터 전달이 κ°„νŽΈν•˜λ‹€.
  • 둜컬 μŠ€ν† λ¦¬μ§€μ— 데이터λ₯Ό μ €μž₯ν•˜κ³  λΆˆλŸ¬μ˜€λŠ” μ½”λ“œλ₯Ό μ‰½κ²Œ μž‘μ„±ν•  수 μžˆλ‹€.
  • 같은 상탯값을 λ‹€μˆ˜μ˜ μ»΄ν¬λ„ŒνŠΈμ—μ„œ ν•„μš”λ‘œ ν•  λ•Œ μ’‹λ‹€.
  • λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ κΉŠμ€ κ³³μ—μ„œ μžˆλŠ” μžμ‹ μ»΄ν¬λ„ŒνŠΈμ— 상탯값을 전달 ν•  λ•Œ μ’‹λ‹€
  • μ•Œλ¦Όμ°½κ³Ό 같은 μ „μ—­ μ»΄ν¬λ„ŒνŠΈμ˜ 상탯값을 관리할 λ•Œ μ’‹λ‹€.
  • νŽ˜μ΄μ§€κ°€ μ „ν™˜λ˜μ–΄λ„ λ°μ΄ν„°λŠ” μ‚΄μ•„ μžˆμ–΄μ•Ό ν•  λ•Œ μ’‹λ‹€.

원칙

  • 전체 상탯값을 ν•˜λ‚˜μ˜ 객체에 μ €μž₯ν•œλ‹€
  • 상탯값은 λΆˆλ³€ 객체닀
  • 상탯값은 순수 ν•¨μˆ˜μ— μ˜ν•΄μ„œλ§Œ λ³€κ²½λ˜μ–΄μ•Ό ν•œλ‹€.

ꡬ성

  • μ•‘μ…˜
  • 미듀웨어
  • λ¦¬λ“€μ„œ
  • μŠ€ν† μ–΄

μ•‘μ…˜

  • type 속성값을 κ°€μ§„ js 객체.
  • action 객체λ₯Ό dispatch λ©”μ„œλ“œμ— λ„£μ–΄μ„œ ν˜ΈμΆœν•˜λ©΄ λ¦¬λ•μŠ€λŠ” 상탯값을 λ³€κ²½ν•˜κΈ° μœ„ν•΄ μœ„ κ·Έλ¦Ό 처럼 μˆ˜ν–‰ν•œλ‹€.
store.dispatch({ type: 'ADD', title: '타이틀 μΆ”κ°€ν•  λ‚΄μš©', priority:'high'})

미듀웨어

  • λ¦¬λ“€μ„œκ°€ μ•‘μ…˜μ„ μ²˜λ¦¬ν•˜κΈ° 전에 μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜λ‹€.
  • 디버깅 λͺ©μ μœΌλ‘œ 상탯값 λ³€κ²½ μ‹œ 둜그λ₯Ό 좜λ ₯ν•˜κ±°λ‚˜, λ¦¬λ“€μ„œμ—μ„œ λ°œμƒν•œ μ˜ˆμ™Έλ₯Ό μ„œλ²„λ‘œ μ „μ†‘ν•˜λŠ” λ“±μ˜ λͺ©μ μœΌλ‘œ ν™œμš© ν•œλ‹€.
const middleware = store => next => action => next(action)

μŠ€ν† μ–΄

  • λ¦¬λ•μŠ€μ˜ 상탯값을 κ°€μ§€λŠ” 객체닀.
  • μ•‘μ…˜μ˜ λ°œμƒμ€ μŠ€ν† μ–΄μ˜ dispatch λ©”μ„œλ“œλ‘œ μ‹œμž‘λœλ‹€
  • μŠ€ν† μ–΄λŠ” μ•‘μ…˜μ΄ λ°œμƒν•˜λ©΄ 미듀웨어 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜κ³ , λ¦¬λ“€μ„œλ₯Ό μ‹€ν–‰ν•΄μ„œ 상탯값을 μƒˆλ‘œμš΄ κ°’μœΌλ‘œ λ³€κ²½ν•œλ‹€.
const INITIAL_STATE = { value: 0};
const reducer = createReducer(INITIAL_STATE, {
  INCREMENT: state => (state.value +=1),
});
const store = createStore(reducer);

비동기 처리 방법

  • λ¦¬λ“€μ„œ μ•ˆμ—μ„œ 비동기λ₯Ό ν•˜κ²Œ 되면 3번 원칙인 '상탯값은 순수 ν•¨μˆ˜μ— μ˜ν•΄μ„œλ§Œ λ³€κ²½λ˜μ–΄μ•Ό ν•œλ‹€.' μœ„λ°°λœλ‹€. κ·Έλž˜μ„œ middlewareμ—μ„œ 처리 ν•˜λŠ”λ° μ΄λ•Œ νŒ¨ν‚€μ§€λ₯Ό μ“΄λ‹€.
  • redux-thunk, redux-observable, redux-saga

좜처: μ‹€μ „ λ¦¬μ•‘νŠΈ ν”„λ‘œκ·Έλž˜λ°, 이재승, μΈμ‚¬μ΄νŠΈ(2020), pg 249~308


Redux (λ¦¬μ•‘νŠΈλ₯Ό λ‹€λ£¨λŠ” 기술 - velopert)

  • λ¦¬μ•‘νŠΈ μƒνƒœ 관리 라이브러리
  • μ»΄ν¬λ„ŒνŠΈμ˜ μƒνƒœ μ—…λ°μ΄νŠΈ κ΄€λ ¨ λ‘œμ§μ„ λ‹€λ₯Έ 파일둜 λΆ„λ¦¬μ‹œμΌœ 효율적인 관리 κ°€λŠ₯
  • μ „μ—­ μƒνƒœλ₯Ό 관리할 λ•Œ 효과적(Context APIλ₯Ό ν†΅ν•΄μ„œλ„ κ°€λŠ₯)
  • ν”„λ‘œμ νŠΈμ˜ 규λͺ¨κ°€ 클 경우 λ¦¬λ•μŠ€ > Context API
    • μ½”λ“œμ˜ μœ μ§€ λ³΄μˆ˜μ„± λ†’μ—¬μ£Όκ³  μž‘μ—…νš¨μœ¨μ„ κ·ΉλŒ€ν™”ν•΄μ£ΌκΈ° λ•Œλ¬Έ

      ex) TODO

μ•‘μ…˜

  • μƒνƒœμ— μ–΄λ– ν•œ λ³€ν™”κ°€ ν•„μš”ν•˜λ©΄ μ•‘μ…˜(action)이 λ°œμƒ

  • ν•˜λ‚˜μ˜ 객체둜 ν‘œν˜„λœλ‹€

  • ν˜•μ‹

    {
    	type: 'ADD_TODO'
    }
  • μ•‘μ…˜ κ°μ²΄λŠ” type ν•„λ“œλ₯Ό λ°˜λ“œμ‹œ κ°€μ§„λ‹€

    • type β‡’ μ•‘μ…˜μ˜ 이름이라고 μƒκ°ν•˜λ©΄ λœλ‹€
    • ex)
    {
    	type: 'ADD_TODO',
    	data: {
    		id: 1,
    		text: 'κ³΅λΆ€ν•˜κΈ°'
    	}
    }
    
    {
    	type: 'CHANGE_INPUT',
    	text: 'μ•ˆλ…•ν•˜μ„Έμš”'
    }

μ•‘μ…˜ 생성 ν•¨μˆ˜

  • μ•‘μ…˜ 객체λ₯Ό λ§Œλ“€μ–΄ μ£ΌλŠ” ν•¨μˆ˜
const addTodo = (data) => ({
	type: 'ADD_TODO',
	data
}) 
  • λ³€ν™”λ₯Ό μΌμœΌμΌœμ•Ό ν•  λ•Œ, 직접 μ•‘μ…˜ 객체λ₯Ό λ§Œλ“€κΈ°λ³΄λ‹€ ν•¨μˆ˜λ‘œ λ§Œλ“€μ–΄μ„œ 관리

λ¦¬λ“€μ„œ(reducer)

  • λ³€ν™”λ₯Ό μΌμœΌν‚€λŠ” ν•¨μˆ˜
  • μ•‘μ…˜μ„ λ§Œλ“€μ–΄μ„œ λ°œμƒμ‹œν‚€λ©΄ λ¦¬λ“€μ„œκ°€ ν˜„μž¬ μƒνƒœμ™€ 전달받은 μ•‘μ…˜ 객체λ₯Ό 인자둜 λ°›μ•„ 옴
  • 인자둜 λ„˜μ–΄μ˜¨ 두 값을 μ°Έκ³ ν•˜μ—¬ μƒˆλ‘œμš΄ μƒνƒœλ₯Ό λ§Œλ“€μ–΄μ„œ λ°˜ν™˜
const initialState = {
	counter: 1
};

const reducer(state = initialState, action) {
	switch(action.type) {
		case INCREMENT:
			return {
				counter: state.counter + 1
			};
		default:
			return state;
	}
}

μŠ€ν† μ–΄

  • ν•œ 개의 ν”„λ‘œμ νŠΈλŠ” 단 ν•˜λ‚˜μ˜ μŠ€ν† μ–΄λ₯Ό κ°€μ§„λ‹€
  • μŠ€ν† μ–΄ μ•ˆμ—λŠ” ν˜„μž¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μƒνƒœ & λ¦¬λ“€μ„œ + λͺ‡ κ°€μ§€ μ€‘μš”ν•œ λ‚΄μž₯ ν•¨μˆ˜
    • μŠ€ν† μ–΄μ˜ λ‚΄μž₯ν•¨μˆ˜
      • λ””μŠ€νŒ¨μΉ˜(dispatch)
        • μ•‘μ…˜μ„ λ°œμƒμ‹œν‚€λŠ” 것
        • dispatch(action)
        • λ””μŠ€νŒ¨μΉ˜ 호좜 β‡’ μŠ€ν† μ–΄λŠ” λ¦¬λ“€μ„œ ν•¨μˆ˜λ₯Ό μ‹€ν–‰μ‹œμΌœμ„œ μƒˆλ‘œμš΄ μƒνƒœ λ§Œλ“ λ‹€
      • ꡬ독(subscribe)
        • λ¦¬μŠ€λ„ˆ ν•¨μˆ˜λ₯Ό νŒŒλΌλ―Έν„°λ‘œ λ„£μ–΄μ„œ ν˜ΈμΆœν•΄μ£Όλ©΄, λ¦¬μŠ€λ„ˆ ν•¨μˆ˜κ°€ μ•‘μ…˜μ΄ λ””μŠ€νŒ¨μΉ˜ 될 λ•Œ (μƒνƒœκ°€ μ—…λ°μ΄νŠΈ 될 λ•Œ) ν˜ΈμΆœλœλ‹€.

λ¦¬μ–΄μŠ€μ˜ μ„Έ κ°€μ§€ κ·œμΉ™

  1. 단일 μŠ€ν† μ–΄
    • 1 app = 1 store
    • 닀쀑 μŠ€ν† μ–΄κ°€ λΆˆκ°€λŠ₯ν•˜μ§€λŠ” μ•Šλ‹€
      • μƒνƒœ 관리가 λ³΅μž‘ν•΄μ§ˆ 수 μžˆμœΌλ―€λ‘œ ꢌμž₯ X
  2. 읽기 μ „μš© μƒνƒœ
    • μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈ ν•  λ•Œ 기쑴의 객체 κ±΄λ“œλ¦¬μ§€ μ•Šκ³  μƒˆλ‘œμš΄ 객체 생성
    • λΆˆλ³€μ„± μ§€μΌœμ£ΌκΈ° μœ„ν•΄ spread μ—°μ‚°μž or immer와 같은 λΆˆλ³€μ„± 라이브러리 μ‚¬μš©
    • λ¦¬λ•μŠ€μ—μ„œλŠ” λ‚΄λΆ€μ μœΌλ‘œ 데이터가 λ³€κ²½λ˜λŠ” 것을 κ°μ§€ν•˜κΈ° μœ„ν•΄ 얕은 비ꡐ검사λ₯Ό ν•œλ‹€
  3. λ¦¬λ“€μ„œλŠ” μˆœμˆ˜ν•œ ν•¨μˆ˜
    • λ³€ν™”λ₯Ό μΌμœΌν‚€λŠ” λ¦¬λ“€μ„œ ν•¨μˆ˜λŠ” 순수 ν•¨μˆ˜μ—¬μ•Ό ν•œλ‹€.
      • λ¦¬λ“€μ„œ ν•¨μˆ˜λŠ” 이전 μƒνƒœμ™€ μ•‘μ…˜ 객체λ₯Ό 인자둜 λ°›λŠ”λ‹€
      • νŒŒλΌλ―Έν„° μ™Έμ˜ 값에 μ˜μ‘΄ν•˜λ©΄ μ•ˆλœλ‹€
      • 이전 μƒνƒœλŠ” κ±΄λ“œλ¦¬μ§€ μ•Šκ³ , λ³€ν™”λ₯Ό μ€€ μƒˆλ‘œμš΄ μƒνƒœ 객체λ₯Ό λ§Œλ“€μ–΄ λ°˜ν™˜ν•œλ‹€
      • λ˜‘κ°™μ€ νŒŒλΌλ―Έν„°λ‘œ 호좜된 λ¦¬λ“€μ„œ ν•¨μˆ˜λŠ” 같은 κ²°κ³Ό 값을 λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€
    • λ¦¬λ“€μ„œ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ λžœλ€κ°’ λ§Œλ“€κΈ°, Date ν•¨μˆ˜ μ‚¬μš©ν•˜κΈ°, λ„€νŠΈμ›Œν¬ μš”μ²­ν•˜κΈ° X

Redux - React App μž‘μ—… ν™˜κ²½ μ„€μ •

UI

λ¦¬μ•‘νŠΈ ν”„λ‘œμ νŠΈμ—μ„œ λ¦¬λ•μŠ€λ₯Ό μ‚¬μš©ν•  λ•Œ κ°€μž₯ 많이 μ‚¬μš©ν•˜λŠ” νŒ¨ν„΄μ€ ν”„λ ˆμ  ν…Œμ΄μ…”λ„ μ»΄ν¬λ„ŒνŠΈμ™€ μ»¨ν…Œμ΄λ„ˆ μ»΄ν¬λ„ŒνŠΈλ₯Ό λΆ„λ¦¬ν•˜λŠ” 것.

  • ν”„λ ˆμ  ν…Œμ΄μ…”λ„ μ»΄ν¬λ„ŒνŠΈ
    • μƒνƒœ 관리 X
    • propsλ₯Ό λ°›μ•„μ™€μ„œ 화면에 UIλ₯Ό λ³΄μ—¬μ£ΌκΈ°λ§Œ ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  • μ»¨ν…Œμ΄λ„ˆ μ»΄ν¬λ„ŒνŠΈ
    • λ¦¬λ•μŠ€μ™€ μ—°λ™λ˜μ–΄ μžˆλŠ” μ»΄ν¬λ„ŒνŠΈλ‘œ
    • λ¦¬λ•μŠ€λ‘œλΆ€ν„° μƒνƒœλ₯Ό λ°›μ•„μ˜€κΈ°λ„, λ¦¬λ•μŠ€ μŠ€ν† μ–΄μ— μ•‘μ…˜μ„ λ””μŠ€νŒ¨μΉ˜ ν•˜κΈ°λ„ ν•œλ‹€.

μž₯점

  • μ½”λ“œμ˜ μž¬μ‚¬μš©μ„±
  • κ΄€μ‹¬μ‚¬μ˜ 뢄리가 이루어져 UIλ₯Ό μž‘μ„±ν•  λ•Œ μ’€ 더 집쀑할 수 μžˆλ‹€.

image

  • UI에 κ΄€λ ¨λœ ν”„λ ˆμ  ν…Œμ΄μ…”λ„ μ»΄ν¬λ„ŒνŠΈ β‡’ src/components
  • λ¦¬λ•μŠ€μ™€ μ—°λ™λœ μ»¨ν…Œμ΄λ„ˆ μ»΄ν¬λ„ŒνŠΈ β‡’ src/containers

Redux DevTools 의 μ„€μΉ˜ 및 적용

  • Redux 개발자 도ꡬ
  • 크둬 ν™•μž₯ ν”„λ‘œκ·Έλž¨μœΌλ‘œ μ„€μΉ˜ν•˜μš” μ‚¬μš©κ°€λŠ₯
  • νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•˜μ—¬ μ μš©ν•˜λŠ” 것 μΆ”μ²œ
    • yarn add redux-devtools-extension
import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";
import { composeWithDevTools } from "redux-devtools-extension";
import App from "./App";
import rootReducer from "./modules";

const store = createStore(rootReducer, composeWithDevTools());

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

image 좜처: λ¦¬μ•‘νŠΈλ₯Ό λ‹€λ£¨λŠ” 기술(velopertλ‹˜)

Clone this wiki locally