Redux
1. ์ํ ๊ด๋ฆฌ
์ ์ญ ์ํ ๊ด๋ฆฌ
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์์์ ์ํ: ๋์ ์ผ๋ก ํํ๋๋ ๋ฐ์ดํฐ
์ ์ญ ์ํ
์๋ก ๋ค๋ฅธ ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฉํ๋ ์ํ์ ์ข ๋ฅ๊ฐ ๋ค๋ฅด๋ค๋ฉด, ์๋ก ๋ค๋ฅธ ์ถ์ฒ๊ฐ ์์ด๋ ๊ด์ฐฎ์
ํ์ง๋ง ์๋ก ๋ค๋ฅธ ์ปดํฌ๋ํธ๊ฐ ๋์ผํ ์ํ๋ฅผ ๋ค๋ฃฌ๋ค๋ฉด, ์๋ก ๋ค๋ฅธ ์ถ์ฒ๋ก ๊ฐ์ ธ์ค๋ ๊ฒ์ ํผํ๋ ๊ฒ์ด ์ข์
๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ
๋์ผํ ๋ฐ์ดํฐ๋ ํญ์ ๊ฐ์ ๊ณณ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค. โ Single source of truth
์ํ ๊ด๋ฆฌ ํด์ด ํด๊ฒฐํด์ฃผ๋ ๋ฌธ์ ๋ค
์ ์ญ ์ํ ์ ์ฅ์ ์ ๊ณต
Props Drilling ์ด์ ํด๊ฒฐ
Props Drilling
์์ ์ปดํฌ๋ํธ์ state๋ฅผ props๋ฅผ ํตํด ์ ๋ฌํ๊ณ ์ ํ๋ ์ปดํฌ๋ํธ๋ก ์ ๋ฌํ๊ธฐ ์ํด
๊ทธ ์ฌ์ด๋ props๋ฅผ ์ ๋ฌํ๋ ์ฉ๋๋ก๋ง ์ฐ์ด๋ ์ปดํฌ๋ํธ๋ค์ ๊ฑฐ์น๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ํ์
Props Drilling์ ๋ฌธ์
์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋๋น ์ง
์ฝ๋์ ์ ์ง๋ณด์ ๋ํ ํ๋ค์ด์ง
state ๋ณ๊ฒฝ ์, Props์ ์ ๋ฌ ๊ณผ์ ์์ ๋ถํ์ํ๊ฒ ๊ด์ฌ๋ ์ปดํฌ๋ํธ๋ค ๋ํ ๋ฆฌ๋ ๋๋ง ๋ฐ์ํด ์ฑ๋ฅ์ ์ ์ํฅ
์ด์ ๋ํ ํด๊ฒฐ์ฑ
์ปดํฌ๋ํธ์ ๊ด๋ จ์๋ state๋ ๊ฐ๋ฅํ๋ฉด ๊ฐ๊น์ด ์ ์งํ๊ธฐ
์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ: ์ ์ญ์ผ๋ก ๊ด๋ฆฌํ๋ ์ ์ฅ์์์ ์ง์ state ๊บผ๋ด ์ธ ์ ์๊ธฐ์ Props Drilling ๋ฐฉ์ง ํจ๊ณผ์
2. Redux๋
์ปดํฌ๋ํธ์ ์ํ๋ฅผ ๋ถ๋ฆฌํ์ฌ ์ ์ญ์์ ์ํ ๊ด๋ฆฌ๋ฅผ ํด์ค ์ ์๊ฒ ํด์ฃผ๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
Redux๊ฐ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ์์
์ํ๊ฐ ๋ณ๊ฒฝ๋์ด์ผ ํ๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด, ๋ณ๊ฒฝ๋ ์ํ์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด Action ๊ฐ์ฒด๊ฐ ์์ฑ
์ด Action ๊ฐ์ฒด๋ Dispatch ํจ์์ ์ธ์๋ก ์ ๋ฌ๋จ
Dispatch ํจ์๋ Action ๊ฐ์ฒด๋ฅผ Reducer ํจ์๋ก ์ ๋ฌํจ
Reducer ํจ์๋ Action ๊ฐ์ฒด์ ๊ฐ์ ํ์ธํ๊ณ , ๊ทธ ๊ฐ์ ๋ฐ๋ผ ์ ์ญ ์ํ ์ ์ฅ์ Store์ ์ํ๋ฅผ ๋ณ๊ฒฝํจ
์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด, React๋ ํ๋ฉด์ ๋ค์ ๋ ๋๋ง
์ฆ, Redux์์๋ Action โ Dispatch โ Reducer โ Store ์์๋ก ๋ฐ์ดํฐ๊ฐ ๋จ๋ฐฉํฅ์ผ๋ก ํ๋ฆ
3. Redux ๊ตฌ์กฐ
Store
์ํ๊ฐ ๊ด๋ฆฌ๋๋ ์ค์ง ํ๋๋ฟ์ธ ์ ์ฅ์ ์ญํ ๋ก, Redux ์ฑ์ state๊ฐ ์ ์ฅ๋์ด ์๋ ๊ณต๊ฐ
// `createStore` ๋ฉ์๋๋ก Reducer ์ฐ๊ฒฐํด store ์์ฑ
import { createStore } from 'redux';
const store = createStore(rootReducer);
Reducer
Dispatch์๊ฒ์ ์ ๋ฌ๋ฐ์ Action ๊ฐ์ฒด์ type ๊ฐ์ ๋ฐ๋ผ์ ์ํ๋ฅผ ๋ณ๊ฒฝ์ํค๋ ํจ์
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๊ฐ ๋ฆฌํดํ๋ ๊ฐ์ด ์๋ก์ด ์ํ๊ฐ ๋จ
// ์ด๋ Reducer๋ ์์ํจ์์ฌ์ผ ํจ.
Action
Action์ ์ด๋ค ์ก์ ์ ์ทจํ ๊ฒ์ธ์ง ์ ์ํด ๋์ ๊ฐ์ฒด๋ก, type์ ํ์๋ก ์ง์ ํด ์ฃผ์ด์ผ ํ๋ฉฐ, ๋๋ฌธ์์ Snake Case๋ก ์์ฑํจ. ๋ณดํต Action ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ํจ์๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ๋๋ฐ, ์ด๋ฅผ ์ก์ ์์ฑ์ (Action Creator)๋ผ๊ณ ํจ.
// payload๊ฐ ํ์ ์๋ ๊ฒฝ์ฐ
const increase = () => {
return {
type: 'INCREASE'
}
}
// payload๊ฐ ํ์ํ ๊ฒฝ์ฐ
const setNumber = (num) => {
return {
type: 'SET_NUMBER',
payload: num
}
}
Dispatch
Reducer๋ก Action์ ์ ๋ฌํด ์ฃผ๋ ํจ์
// Action ๊ฐ์ฒด๋ฅผ ์ง์ ์์ฑํ๋ ๊ฒฝ์ฐ
dispatch( {type: 'INCREASE'} );
dispatch( {type: 'SET_NUMBER', payload: 5} );
// Action Creator๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
dispatch( increase() );
dispatch( setNumber(5) );
4. Redux Hooks
useDispatch()
Action ๊ฐ์ฒด๋ฅผ Reducer๋ก ์ ๋ฌํด ์ฃผ๋ Dispatch ํจ์๋ฅผ ๋ฐํํ๋ ๋ฉ์๋
import {useDispatch} from 'react-redux'
const dispatch = useDispatch()
dispatch(increase())
console.log(counter) // 2
dispatch(setNumber(5))
console.log(counter) // 5
useSelector()
์ปดํฌ๋ํธ์ state๋ฅผ ์ฐ๊ฒฐํด Redux์ state์ ์ ๊ทผํ ์ ์๊ฒ ํด์ฃผ๋ ๋ฉ์๋
// Redux Hooks ๋ฉ์๋๋ redux๊ฐ ์๋ react-redux์์ ๋ถ๋ฌ์ด
import {useSelector} from 'react-redux'
const counter = useSelector(state => state)
console.log(counter) // 1
5. Redux์ ์ธ ๊ฐ์ง ์์น
Single source of truth
๋์ผํ ๋ฐ์ดํฐ๋ ํญ์ ๊ฐ์ ๊ณณ์์ ๊ฐ์ง๊ณ ์์ผ ํจ
Redux์๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ Store ๋ผ๋ ํ๋๋ฟ์ธ ๊ณต๊ฐ์ด ์์
State is read-only
์ํ๋ ์ฝ๊ธฐ ์ ์ฉ
React์์ ์ํ๊ฐฑ์ ํจ์๋ก๋ง ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ฒ๋ผ Redux์ ์ํ๋ ์ง์ ๋ณ๊ฒฝํ ์ ์์์ ์๋ฏธ
์ฆ, Action ๊ฐ์ฒด๊ฐ ์์ด์ผ๋ง ์ํ๋ฅผ ๋ณ๊ฒฝ ๊ฐ๋ฅ
Changes are made with pure functions
๋ณ๊ฒฝ์ ์์ํจ์๋ก๋ง ๊ฐ๋ฅ
์ํ๊ฐ ์๋ฑํ ๊ฐ์ผ๋ก ๋ณ๊ฒฝ๋๋ ์ผ์ด ์๋๋ก ์์ํจ์๋ก๋ง ์์ฑ๋์ด์ผ ํจ
Last updated