Redux
β’
Redux λ?
β¦
Reduce
β¦
Flux
β’
Redux μ΄ν΄νκΈ°
β’
Redux κΈ°λ³Έ μ리
β’
Redux κ΅¬μ± μμ
β¦
μ€ν μ΄
β¦
μ‘μ
β¦
리λμ
β¦
λμ€ν¨μΉ
β’
Redux λμ κ³Όμ
β¦
μ΄λ²€νΈ λ°μ
β¦
μ‘μ
λ°μ
β¦
λμ€ν¨μΉ
β¦
리λμ μ€ν
β¦
μν μ
λ°μ΄νΈ
β¦
ꡬλ
μ μλ¦Ό
β’
Redux κ΄λ ¨ λΌμ΄λΈλ¬λ¦¬
β’
μμ μ½λ
Redux λ?
Reduce + Flux
: λ¨λ°©ν₯ λ°μ΄ν° νλ¦ κΈ°λ° μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬
Reduce
μλ°μ€ν¬λ¦½νΈμ reduce ν¨μλ λ°°μ΄μ μννλ©΄μ λμ κ°μ κ³μ°νλ ν¨μ
Flux
μν κ΄λ¦¬λ₯Ό λ¨μννκ³ μμΈ‘ κ°λ₯νκ² νλ λ¨λ°©ν₯ λ°μ΄ν° νλ¦ μν€ν
μ²
(FaceBook μ΄ λ§λ μ ν리μΌμ΄μ
μν€ν
μ²)
Redux μ΄ν΄νκΈ°
1.
κΈ°μμ² & μμ²μκ° λ°©μ‘κ΅μΌλ‘ νμ₯μ κΈ°μ μν©μ μ 보ν©λλ€.
2.
λ°©μ‘κ΅ μ€νλμ€μμλ λ°λκΈ° κΈ°μλ₯Ό νμ₯μΌλ‘ ν견ν©λλ€.
3.
λ°λκΈ° κΈ°μλ νμ₯μμ λκΈ°νλ©° νμ¬ λ μ¨μ λ μ¨ λ³νμ κ°λλ₯Ό μ·¨μ¬νκ³ , νμ₯μ 컨νΈλ‘€ νμμΈ PDλ μλ‘μ΄ λ μ¨ μν©μ λΌμ΄λΈλ‘ λ°©μ‘ν©λλ€.
4.
μ΄ νμ₯ κΈ°μ μν© λ΄μ€λ₯Ό μμ²μλ€μ΄ μμ²ν©λλ€.
μμ²μκ° μ 보λ₯Ό νλ λͺ¨μ΅μ λ§μΉ, Redux λμ κ³Όμ μ μ΄λ²€νΈ λ°μκ³Ό μ μ¬ν©λλ€. μ΄ μ 보λ₯Ό λ°μ λ°©μ‘κ΅ μ€νλμ€λ νμ₯μ κ°μ μ΄λ€ μ‘μ
μ μ·¨ν΄μΌν μ§ μ νκ³ λ°λκΈ° κΈ°μλ₯Ό ν견νλλ°, λ°λκΈ° κΈ°μλ₯Ό ν견νλ κ³Όμ μ Redux λμ κ³Όμ μ Dispatch μ μ μ¬ν©λλ€.
μ‘μ
μ κ°μ§κ³ ν견λ λ°λκΈ° κΈ°μμ νμ₯μ μλ PDλ νμ¬ μν©κ³Ό μ‘μ
μ νμ
νκ³ , μλ‘μ΄ λ μ¨ μν©μ μ·¨μ¬νμ¬ λ°©μ‘ν©λλ€. μ΄ κ³Όμ μ λ§μΉ State μ Action μ μ λ¬ λ°μ μλ‘μ΄ State λ₯Ό λ°ννλ 리λμμ λμ κ³Όμ κ³Ό μ μ¬ν©λλ€.
μ΄μ΄μ μ΄ λ°©μ‘ λ΄μ€λ₯Ό ν΅ν΄ μλ‘μ΄ λ μ¨ μν©μ΄ μμ²μλ€μκ² μ λ¬λκ³ λ μ¨μ μν₯μ λ°λ μ§μμ μ λ¬λλ κ³Όμ μ Redux λμ κ³Όμ μμ Store λ₯Ό ꡬλ
ν μ»΄ν¬λνΈλ€μ΄ μν λ³νλ₯Ό μ λ¬ λ°λ κ³Όμ κ³Ό μ μ¬ν©λλ€.
1.
νμ¬ νμ₯μμ 119 μ μ ννμ¬ μ 보ν©λλ€.
2.
119 μν©μ€μμ μλ°© λΉκ΅μ νμ¬ νμ₯ μ 보μ λνμ¬ λ³΄κ³ ν©λλ€.
3.
μλ°© λΉκ΅μ 119 μν©μ€λ‘ μ λ¬ λ°μ, μ±
μμμ νμ¬ λ¨κ³μ λμ λ°©ν₯μ μ λ¬ λ°μ μλ‘μ΄ λμ λ¨κ³λ₯Ό λ°νν©λλ€.
4.
μ΄μ λ°λΌ, λμ λ¨κ³μ λ§λ νμ¬ νμ₯μ λμμ΄ μ΄λ£¨μ΄μ§λλ€.
μ΄λ κ² νμ¬ νμ₯μ μ λ³΄κ° 119 μν©μ€μ μ λ¬λκ³ , μ΄μ λν μλ°© λΉμ λμ λ¨κ³λ₯Ό μλ°© λΉκ΅ 컨νΈλ‘€ νμμμ μ²λ¦¬νμ¬ μλ‘μ΄ λμ λ¨κ³λ₯Ό λ°ννκ³ νμ¬ νμ₯μ λμνλ κ³Όμ μ λ§μΉ Redux μ λμ κ³Όμ κ³Ό μ μ¬ν©λλ€.
리λμ€ μ ν리μΌμ΄μ
μμ μν κ΄λ¦¬κ° μ΄λ£¨μ΄μ§λ κ³Όμ μ λ¨κ³λ³λ‘ μ΄ν΄λ³΄κ² μ΅λλ€. λ¨Όμ , μ‘μ
λ°μ λ¨κ³μμλ μ¬μ©μκ° UIμ μνΈμμ©νκ±°λ λ€λ₯Έ μ΄λ²€νΈκ° λ°μν λ μ‘μ
μ΄ μμ±λ©λλ€. μλ₯Ό λ€μ΄, μ¬μ©μκ° λ²νΌμ ν΄λ¦νλ©΄ μ‘μ
μ΄ λ°μν©λλ€. μ΄ μ‘μ
μ μν λ³κ²½μ μ§μνλ μ 보λ₯Ό λ΄κ³ μμ΅λλ€.
λ€μμΌλ‘, λμ€ν¨μΉ λ¨κ³κ° μμ΅λλ€. μμ±λ μ‘μ
μ dispatch λ©μλλ₯Ό ν΅ν΄ μ€ν μ΄μ μ λ¬λ©λλ€. μ΄ κ³Όμ μ μ‘μ
μ μ€ν μ΄μ 보λ΄λ μν μ νλ©°, μ΄λ₯Ό ν΅ν΄ μν λ³κ²½μ μμ²ν©λλ€.
μ΄ν 리λμ μ€ν λ¨κ³μμ μ€ν μ΄λ ν΄λΉ μ‘μ
μ 리λμλ‘ μ λ¬ν©λλ€. 리λμλ νμ¬ μνμ μ λ¬λ μ‘μ
μ κΈ°λ°μΌλ‘ μλ‘μ΄ μνλ₯Ό κ³μ°ν©λλ€. 리λμλ μμ ν¨μλ‘, μ£Όμ΄μ§ μ
λ ₯(νμ¬ μνμ μ‘μ
)μ λ°λΌ λμΌν μΆλ ₯(μλ‘μ΄ μν)μ λ°νν©λλ€.
μν μ
λ°μ΄νΈ λ¨κ³μμλ 리λμκ° λ°νν μλ‘μ΄ μνκ° μ€ν μ΄μ μ μ₯λ©λλ€. μ€ν μ΄λ νμ νμ¬ μ ν리μΌμ΄μ
μ μνλ₯Ό 보μ νκ³ μμΌλ©°, 리λμλ₯Ό ν΅ν΄ κ³μ°λ μνλ₯Ό μ΅μ μνλ‘ μ μ§ν©λλ€.
λ§μ§λ§μΌλ‘, ꡬλ
μ μλ¦Ό λ¨κ³κ° μ§νλ©λλ€. μ€ν μ΄λ μνκ° λ³κ²½λ λλ§λ€ ꡬλ
λ λͺ¨λ 리μ€λμκ² μν λ³ν μ¬μ€μ ν΅μ§ν©λλ€. 리μ€λλ μΌλ°μ μΌλ‘ 리μ‘νΈ μ»΄ν¬λνΈλ‘, μν λ³νκ° λ°μνλ©΄ μ»΄ν¬λνΈλ μλ‘μ΄ μνλ₯Ό λ°μνμ¬ μλμΌλ‘ 리λ λλ§λ©λλ€. μ΄λ₯Ό ν΅ν΄ μ ν리μΌμ΄μ
μ UIλ νμ μ΅μ μνλ₯Ό λ°μνκ² λ©λλ€.
μ΄λ¬ν λ¨κ³λ€μ΄ λͺ¨μ¬ 리λμ€ μ ν리μΌμ΄μ
μ μν κ΄λ¦¬ νλ¦μ ꡬμ±ν©λλ€. μ΄ κ³Όμ μ μν λ³κ²½μ μμΈ‘ κ°λ₯νκ³ μΌκ΄μ± μκ² μ μ§νλλ‘ λμ΅λλ€.
Redux κΈ°λ³Έ μμΉ
β’
λ¨μΌ μ§μ€μ κ·Όμ: μ ν리μΌμ΄μ
μ λͺ¨λ μνλ νλμ μ€ν μ΄(store)μ μ μ₯λ©λλ€. μ΄λ μνλ₯Ό μ½κ² μΆμ νκ³ λλ²κΉ
νλ λ° λμμ μ€λλ€.
β’
μνλ μ½κΈ° μ μ©: μνλ₯Ό μ§μ μμ νμ§ μκ³ , μ‘μ
(action)μ ν΅ν΄μλ§ μνλ₯Ό λ³κ²½ν μ μμ΅λλ€.
β’
λ³κ²½μ μμ ν¨μ(reducer)λ‘: μνμ μ‘μ
μ μ
λ ₯λ°μ μλ‘μ΄ μνλ₯Ό λ°ννλ μμ ν¨μμΈ λ¦¬λμ(reducer)λ₯Ό ν΅ν΄ μνκ° λ³κ²½λ©λλ€.
Redux κ΅¬μ± μμ
β’
μ‘μ
β’
λμ€ν¨μΉ
β’
μ€ν μ΄
β’
리λμ
μ‘μ (Action)
type + payload
: μ΄λ€ μ΄λ²€νΈκ° μΌμ΄λμ μ΄λ€ μνκ° λ³κ²½λμΌνλμ§ λνλ΄λ κ°μ²΄
β’
type : μ‘μ
μ μ’
λ₯
β’
payload : λ°μ΄ν°
λμ€ν¨μΉ (Dispatch)
μ‘μ
μ μ€ν μ΄μ 보λ΄λ ν¨μ
μ€ν μ΄ (Store)
μ ν리μΌμ΄μ
μν μ μ₯μ
리λμ (Reducer)
νμ¬ μνμ μ‘μ
μ λ°μμ μλ‘μ΄ μνλ₯Ό λ°ννλ ν¨μ
Redux λμ κ³Όμ
1.
μ‘μ
λ°μ
: UIλ λ€λ₯Έ μ΄λ²€νΈμ μν΄ μ‘μ
μ΄ λ°μν©λλ€.
2.
λμ€ν¨μΉ
: μ‘μ
μ μ€ν μ΄μ λμ€ν¨μΉν©λλ€.
3.
리λμ μ€ν
: μ€ν μ΄λ 리λμλ₯Ό νΈμΆνμ¬ μλ‘μ΄ μνλ₯Ό κ³μ°ν©λλ€.
4.
μν μ
λ°μ΄νΈ
: μλ‘μ΄ μνκ° μ€ν μ΄μ μ μ₯λ©λλ€.
5.
ꡬλ
μ μλ¦Ό
: μ€ν μ΄μ ꡬλ
λ λͺ¨λ 리μ€λ(μ»΄ν¬λνΈ λ±)μκ² μν λ³νκ° ν΅μ§λ©λλ€.
Redux κ΄λ ¨ λΌμ΄λΈλ¬λ¦¬
β’
redux
β’
react-redux
β’
redux-devtools-extension
β’
redux-actions
Redux λΌμ΄λΈλ¬λ¦¬ μ€μΉ
npm install redux react-redux redux-devtools-extension redux-actions
Bash
볡μ¬
npm install redux
npm install react-redux
npm install redux-devtools-extension
npm install redux-actions
Bash
볡μ¬
redux
Reduxλ μλ°μ€ν¬λ¦½νΈ μ ν리μΌμ΄μ
μ μν μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬μ
λλ€. μ ν리μΌμ΄μ
μ μνλ₯Ό μμΈ‘ κ°λ₯ν λ°©μμΌλ‘ κ΄λ¦¬ν μ μκ² ν΄μ£Όλ©°, μ£Όλ‘ Reactμ ν¨κ» μ¬μ©λ©λλ€. Reduxλ λ¨μΌ μ€ν μ΄, μ‘μ
, 리λμ, λ―Έλ€μ¨μ΄ λ±μ ν΅ν΄ μνλ₯Ό κ΄λ¦¬ν©λλ€.
npm install redux
Bash
볡μ¬
react-redux
React-Reduxλ Reduxμ Reactλ₯Ό μ°κ²°ν΄μ£Όλ 곡μ λ°μΈλ© λΌμ΄λΈλ¬λ¦¬μ
λλ€. React μ»΄ν¬λνΈκ° Redux μ€ν μ΄μ μνΈμμ©ν μ μλλ‘ λμμ€λλ€. Provider μ»΄ν¬λνΈλ₯Ό μ¬μ©νμ¬ Redux μ€ν μ΄λ₯Ό React μ»΄ν¬λνΈ νΈλ¦¬μ μ£Όμ
νκ³ , connect ν¨μλ useSelector λ° useDispatch ν
μ μ¬μ©νμ¬ μ»΄ν¬λνΈκ° μνλ₯Ό μ½κ³ μ‘μ
μ λμ€ν¨μΉν μ μκ² ν©λλ€.
npm install react-redux
Bash
볡μ¬
redux-devtools-extension
Redux DevTools Extensionμ Redux μνμ μ‘μ
μ λλ²κ·Ένλ λ° λμμ μ£Όλ λΈλΌμ°μ νμ₯ νλ‘κ·Έλ¨μ
λλ€. μ΄ νμ₯μ μ¬μ©νλ©΄ μ ν리μΌμ΄μ
μ μν λ³νλ₯Ό μκ°μ μΌλ‘ μΆμ νκ³ , νμ νΈλλΈ λλ²κΉ
μ ν΅ν΄ μνλ₯Ό μ΄μ λ¨κ³λ‘ λλ릴 μ μμ΅λλ€.
npm install redux-devtools-extension
Bash
볡μ¬
redux-actions
Redux-Actionsλ Reduxμμ μ‘μ
μμ±μμ 리λμλ₯Ό κ°κ²°νκ² μ μν μ μκ² ν΄μ£Όλ μ νΈλ¦¬ν° λΌμ΄λΈλ¬λ¦¬μ
λλ€. createActionκ³Ό handleActions κ°μ ν¨μλ€μ μ 곡νμ¬ μ‘μ
μμ±κ³Ό 리λμ μ μλ₯Ό λ¨μνν©λλ€.
npm install redux-actions
Bash
볡μ¬
μμμ½λ
β’
μΉ΄μ΄ν° μ± νλ‘μ νΈ
β’
νλ‘μ νΈ μμ±
β’
λΌμ΄λΈλ¬λ¦¬ μ€μΉ
β’
μ½λ μμ
β¦
μ‘μ
νμ
μ μΈ
β¦
μ‘μ
μμ± ν¨μ μ μ
β¦
리λμ ν¨μ μ μ
β¦
μ€ν μ΄ μ μ
β¦
UI νλ©΄
β¦
Store Provider
μΉ΄μ΄ν° μ± νλ‘μ νΈ
νλ‘μ νΈ μμ±
npx create-react-app redux-app
Bash
볡μ¬
λΌμ΄λΈλ¬λ¦¬ μ€μΉ
β’
Redux
npm install redux @reduxjs/toolkit react-redux redux-actions
Bash
볡μ¬
β’
bootstrap
npm install bootstrap
Bash
볡μ¬
β’
sweetalert2
npm install sweetalert2 sweetalert2-react-content
Bash
볡μ¬
μ½λ μμ
β’
μ‘μ
νμ
μ μΈ
β’
μ‘μ
μμ± ν¨μ μ μ
β’
리λμ ν¨μ μ μ
β’
μ€ν μ΄ μ μ
β’
UI νλ©΄
μ‘μ νμ μ μΈ
β’
actionTypes.js
// μ‘μ
νμ
μ μ
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
JavaScript
볡μ¬
Reduxμμ μνλ₯Ό λ³κ²½νλ λμ(μ‘μ
)μ λ¬Έμμ΄ μμλ‘ μ μΈνλ μ½λμ
λλ€.
κ·Έ λ κ·Έ λ νμν κ³³μμ λ¬Έμμ΄λ‘ μ‘μ
μ λνλ΄λ λμ§λ§, λ¬Έμμ΄ μμλ‘ μ μΈνλ©΄ μ€νλ‘ μΈν λ²κ·Έλ₯Ό λ°©μ§ν μ μλ μ΄μ μ΄ μμ΅λλ€.
μ‘μ μμ± ν¨μ μ μ
// μ‘μ
μμ± ν¨μ μ μ
import { createAction } from 'redux-actions';
import { DECREMENT, INCREMENT } from './actionTypes';
export const increment = createAction(INCREMENT)
export const decrement = createAction(DECREMENT)
JavaScript
볡μ¬
Redux μ‘μ
μμ± ν¨μλ₯Ό μ μν μ½λμ
λλ€.
createAction ν¨μ
μ‘μ
νμ
μ μΈμλ‘ μ§μ νμ¬, ν΄λΉ νμ
μ κ°μ§ μ‘μ
μμ± ν¨μλ₯Ό λ°ννλ ν¨μ
createAction ν¨μλ‘ μ‘μ
μ μμ±νλ ν¨μλ₯Ό λ§λλλ€. μμ μ½λμμλ μΉ΄μ΄νΈλ₯Ό μ¦κ°μν€λ μλ―Έμ βINCREMENTβ μ‘μ
νμ
κ³Ό μΉ΄μ΄νΈλ₯Ό κ°μμν€λ μλ―Έλ‘ βDECREMENTβ μ‘μ
νμ
μ κ°μ§ increment(), decrement() μ‘μ
μμ±ν¨μλ₯Ό μ μν©λλ€.
μ΄λ κ² μ‘μ
μμ± ν¨μλ₯Ό μ μνλ©΄, μ΄λ²€νΈ νΈλ€λ¬μμ dispatch() ν¨μλ₯Ό νΈμΆνλ©΄μ ν΄λΉ μ΄λ²€νΈμ μ°κ²°λ μ‘μ
μμ± ν¨μλ₯Ό μ λ¬νλ©΄ μ€ν μ΄μ 미리 μ μλ μ‘μ
μ μ λ¬ν μ μμ΅λλ€.
리λμ ν¨μ μ μ
// 리λμ μ μ
import { handleActions } from 'redux-actions';
import { DECREMENT, INCREMENT } from './actionTypes';
// μν μ΄κΈ°ν
const initialState = {
count : 0
}
// 리λμ
const counterReducer = handleActions(
{
[INCREMENT] : (state) => ( {count: state.count + 1} ),
[DECREMENT] : (state) => ( {count: state.count - 1} ),
},
initialState
)
export default counterReducer;
JavaScript
볡μ¬
redux-actions λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ λ¦¬λμλ₯Ό μ μνλ μ½λμ
λλ€.
μ€ν μ΄ μ μ
// μ€ν μ΄ μ μ
import { configureStore } from '@reduxjs/toolkit'
import rootReducer from './reducers';
const store = configureStore({
reducer: rootReducer
});
export default store;
JavaScript
볡μ¬
UI νλ©΄
β’
App.js
import { useDispatch, useSelector } from 'react-redux';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import { decrement, increment } from './redux/actions';
function App() {
// μ€ν μ΄μ μν μ ν : count
const count = useSelector( (state) => state.count )
// λμ€ν¨μΉ
const dispatch = useDispatch()
return (
<div className="container d-flex flex-column justify-content-center align-items-center" style={{ minHeight: '100vh' }}>
<div className="card text-center p-4 shadow">
<h1 className="card-title">Counter</h1>
<h3>{count}</h3>
<div className="card-body">
<button className='btn btn-primary me-2'
onClick={() => dispatch(increment())}
>+</button>
<button className='btn btn-danger'
onClick={() => dispatch(decrement())}
>-</button>
</div>
</div>
</div>
);
}
export default App;
JavaScript
볡μ¬
Store Provider
β’
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import store from './redux/store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{/* β Providerλ₯Ό μ¬μ©νμ¬ Redux μ€ν μ΄λ₯Ό React μ ν리μΌμ΄μ
μ μ 곡 */}
<Provider store={ store }>
<App /> {/* β App λ° νμ μ»΄ν¬λνΈμμ Redux μ€ν μ΄μ μ κ·Ό κ°λ₯ */}
</Provider>
</React.StrictMode>
);
reportWebVitals();
JavaScript
볡μ¬