๐Ÿ–ฅFrontEnd/Redux

TIL) REDUX, redux ๊ธฐ์ดˆ, ๋ฆฌ๋•์Šค ๊ตฌ์กฐ, Redux์˜ ์„ธ ๊ฐ€์ง€ ์›์น™

hellohailie 2022. 7. 6. 21:51

 

1. Redux๋ฅผ ์™œ ์“ฐ๋Š”๊ฐ€?

  1. ํ•ด๋‹น ์ƒํƒœ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ, ์ปดํฌ๋„ŒํŠธ1, ์ปดํฌ๋„ŒํŠธ2๋„ ์ƒํƒœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง
  2. ์ƒํƒœ ๋Œ์–ด์˜ฌ๋ฆฌ๊ธฐ, Props ๋‚ด๋ ค์ฃผ๊ธฐ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ฑฐ์ณ์•ผ ํ•จ
  3. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ๋ฐ์ดํ„ฐ ํ๋ฆ„๋„ ๋ณต์žกํ•ด์ง
  4. ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€๋‹ค๋ฉด, ์ง€๊ธˆ์˜ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์™„์ „ํžˆ ๋ฐ”๊ฟ”์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Œ

โžฅ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Redux๋Š”, ์ „์—ญ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ €์žฅ์†Œ์ธ Store๋ฅผ ์ œ๊ณตํ•ด์„œ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๊น”๋”ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.

 

2. Redux์˜ ๊ตฌ์กฐ

Action ๊ฐ์ฒด ⇒ Dispatch ํ•จ์ˆ˜ ⇒ Reducer ํ•จ์ˆ˜ ⇒ ์ „์—ญ ์ƒํƒœ ์ €์žฅ์†Œ Store ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ ⇒ ํ™”๋ฉด ๋ฆฌ๋ Œ๋”๋ง

  1. ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ๋ณ€๊ฒฝ๋  ์ƒํƒœ์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด Action ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  2. ์ด Action ๊ฐ์ฒด๋Š” Dispatch ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
  3. Dispatch ํ•จ์ˆ˜๋Š” Action ๊ฐ์ฒด๋ฅผ Reducer ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค.
  4. Reducer ํ•จ์ˆ˜๋Š” Action ๊ฐ์ฒด์˜ ๊ฐ’์„ ํ™•์ธํ•˜๊ณ , ๊ทธ ๊ฐ’์— ๋”ฐ๋ผ ์ „์—ญ ์ƒํƒœ ์ €์žฅ์†Œ Store์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  5. ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, React๋Š” ํ™”๋ฉด์„ ๋‹ค์‹œ ๋ Œ๋”๋ง ํ•ฉ๋‹ˆ๋‹ค.

 

3. Redux ๋” ์ž์„ธํžˆ ๊ณต๋ถ€ํ•˜๊ธฐ

 

1) **Action // type ์ง€์ • ํ•„์ˆ˜!

(๊ฐ์ฒด๋กœ ๋งŒ๋“ค๊ธฐ)

// payload๊ฐ€ ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ
{ type: 'INCREASE' }

// payload๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ
{ type: 'SET_NUMBER', payload: 5 }

(Action ๊ฐ์ฒด ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค๊ธฐ = Action Creator)

// payload๊ฐ€ ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ
const increase = () => {
  return {
    type: 'INCREASE'
  }
}

// payload๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ
const setNumber = (num) => {
  return {
    type: 'SET_NUMBER',
    payload: num
  }
}

 

2) Dispatch = Reducer๋กœ Action์„ ์ „๋‹ฌํ•ด์ฃผ๋Š” ํ•จ์ˆ˜ // Dispatch์˜ ์ „๋‹ฌ์ธ์ž๋กœ Action ๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋œ๋‹ค.

// Action ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ
dispatch( { type: 'INCREASE' } );
dispatch( { type: 'SET_NUMBER', payload: 5 } );

// ์•ก์…˜ ์ƒ์„ฑ์ž(Action Creator)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
dispatch( increase() );
dispatch( setNumber(5) );

 

3) Reducer = Dispatch์—๊ฒŒ์„œ ์ „๋‹ฌ๋ฐ›์€ Action ๊ฐ์ฒด์˜ type ๊ฐ’์— ๋”ฐ๋ผ์„œ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๋Š” ํ•จ์ˆ˜

Reducer๋Š” ์ˆœ์ˆ˜ํ•จ์ˆ˜์—ฌ์•ผ ํ•œ๋‹ค.

const count = 1

// Reducer๋ฅผ ์ƒ์„ฑํ•  ๋•Œ์—๋Š” ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์ธ์ž๋กœ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.
const counterReducer = (state = count, action) {

  // Action ๊ฐ์ฒด์˜ type ๊ฐ’์— ๋”ฐ๋ผ ๋ถ„๊ธฐํ•˜๋Š” switch ์กฐ๊ฑด๋ฌธ์ž…๋‹ˆ๋‹ค.
  switch (action.type)

    //action === 'INCREASE'์ผ ๊ฒฝ์šฐ
    case 'INCREASE':
			return state + 1

    // action === 'DECREASE'์ผ ๊ฒฝ์šฐ
    case 'DECREASE':
			return state - 1

    // action === 'SET_NUMBER'์ผ ๊ฒฝ์šฐ
    case 'SET_NUMBER':
			return action.payload

    // ํ•ด๋‹น ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์—†์„ ๋• ๊ธฐ์กด ์ƒํƒœ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฆฌํ„ด
    default:
      return state;
}
// Reducer๊ฐ€ ๋ฆฌํ„ดํ•˜๋Š” ๊ฐ’์ด ์ƒˆ๋กœ์šด ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

4) Store = ์ƒํƒœ๊ฐ€ ๊ด€๋ฆฌ๋˜๋Š” ์˜ค์ง ํ•˜๋‚˜๋ฟ์ธ ์ €์žฅ์†Œ์˜ ์—ญํ• 

createStore ๋กœ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ import ํ•  ์ˆ˜ ์žˆ๋‹ค.

const store = createStore(rootReducer);

import { createStore } from 'redux';

 

5) Redux Hooks

 

useSelector() = ์ปดํฌ๋„ŒํŠธ์™€ state๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ Redux์˜ state์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ

// Redux Hooks ๋ฉ”์„œ๋“œ๋Š” 'redux'๊ฐ€ ์•„๋‹ˆ๋ผ 'react-redux'์—์„œ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
import { useSelector } from 'react-redux'
const counter = useSelector(state => state.counterReducer)
console.log(counter) // 1

useDispatch() = Action ๊ฐ์ฒด๋ฅผ Reducer๋กœ ์ „๋‹ฌํ•ด ์ฃผ๋Š” ๋ฉ”์„œ๋“œ

import { useDispatch } from 'react-redux'

const dispatch = useDispatch()
dispatch( increase() )
console.log(counter) // 2

dispatch( setNumber(5) )
console.log(counter) // 5

 

Redux์˜ ์„ธ ๊ฐ€์ง€ ์›์น™

1. Single source of truth

๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋Š” ํ•ญ์ƒ ๊ฐ™์€ ๊ณณ์—์„œ ๊ฐ€์ง€๊ณ  ์™€์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ์ฆ‰, Redux์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” Store๋ผ๋Š” ๋‹จ ํ•˜๋‚˜๋ฟ์ธ ๊ณต๊ฐ„์ด ์žˆ์Œ๊ณผ ์—ฐ๊ฒฐ์ด ๋˜๋Š” ์›์น™์ž…๋‹ˆ๋‹ค.

2. State is read-only

์ƒํƒœ๋Š” ์ฝ๊ธฐ ์ „์šฉ์ด๋ผ๋Š” ๋œป์œผ๋กœ, React์—์„œ ์ƒํƒœ๊ฐฑ์‹ ํ•จ์ˆ˜๋กœ๋งŒ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ, Redux์˜ ์ƒํƒœ๋„ ์ง์ ‘ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, Action ๊ฐ์ฒด๊ฐ€ ์žˆ์–ด์•ผ๋งŒ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Œ๊ณผ ์—ฐ๊ฒฐ๋˜๋Š” ์›์น™์ž…๋‹ˆ๋‹ค.

3. Changes are made with pure functions

๋ณ€๊ฒฝ์€ ์ˆœ์ˆ˜ํ•จ์ˆ˜๋กœ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋œป์œผ๋กœ, ์ƒํƒœ๊ฐ€ ์—‰๋šฑํ•œ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ์ผ์ด ์—†๋„๋ก ์ˆœ์ˆ˜ํ•จ์ˆ˜๋กœ ์ž‘์„ฑ๋˜์–ด์•ผํ•˜๋Š” Reducer์™€ ์—ฐ๊ฒฐ๋˜๋Š” ์›์น™์ž…๋‹ˆ๋‹ค.