UI(Action) ➡️ Dispatch ➡️ Reducer ➡️ Store(상태 변경)

✅ 단방향 패턴
💡 Single source of truth
동일한 데이터는 같은 곳에서 가져와야 한다
store라는 단 하나의 공간과 연결
💡 State is read-only
action 객체가 있어야만 상태를 변경할 수 있음
💡 Changes are made with pure functions
reducer 내의 함수는 순수함수 이어야 한다
📗 Provider 적용
//index.js
import { Provider } from 'react-redux';
//Provider는 redux를 손쉽게 사용할 수 있게 하는 컴포넌트
root.render(
//적용
<Provider>
<App />
</Provider>
);
📗 createStore로 store 생성
//index.js
import { Provider } from 'react-redux';
import { legacy_createStore as createStore } from 'redux';
//import { createStore } from 'redux';
//reducer 생성
const count = 1;
const counterReducer = (state = count, action) => {
switch(action.type){
case 'INCREASE':
return state + 1;
case 'DECREASE' :
return state - 1;
//인자가 필요한 경우
case 'SET_NUMBER'
return action.payload;
//없으면 undefined 됨
default:
return state;
}
}
//reducer 연결하여 store 생성
const store = createStore(counterReducer);
//여러개일 경우
//const rootReducer = combineReducers({
// counterReducer,
// anyReducer,
//});
root.render(
//store 연결
<Provider store={store}>
<App />
</Provider>
);
✅ reducer는 순수함수이어야 함
📗 Action 객체 생성
//index.js
import { Provider } from 'react-redux';
import { legacy_createStore as createStore } from 'redux';
//action 객체 생성
export const increase = () => {
return {
type : 'INCREASE'
};
}
export const decrease = () => {
return {
type : 'DECREASE'
};
}
//payload가 있는 경우
export const setNumber = (num) => {
return{
type : 'SET_NUMBER',
payload: num
}
}
const count = 1;
const counterReducer = (state = count, action) => {
switch(action.type){
case 'INCREASE':
return state + 1;
case 'DECREASE' :
return state - 1;
case 'SET_NUMBER'
return action.payload;
default:
return state;
}
}
const store = createStore(counterReducer);
root.render(
<Provider store={store}>
<App />
</Provider>
);
📗 Dispatch 생성
//App.js
import { useDispatch } from 'react-redux';
import { increase, decrease } from './index.js';
export default function App() {
//reducer로 action을 전달해주는 함수
const dispatch = useDispatch();
const plusNum = () => {
//reducer 호출
//dispatch( { type: 'INCREASE' } );
dispatch(increase());
}
const minusNum = () => {
dispatch(decrease());
}
return (
<div className="container">
<h1>{`Count: ${1}`}</h1>
<div>
<button onClick={plusNum}>+</button>
<button onClick={minusNum}>-</button>
</div>
</div>
);
}
📗 useSelector 생성
//App.js
//useSelector 추가
import { useDispatch, useSelector } from 'react-redux';
import { increase, decrease } from './index.js';
export default function App() {
//store에 저장된 state에 접근
const state = useSelector((state) => state);
const dispatch = useDispatch();
const plusNum = () => {
dispatch(increase());
}
const minusNum = () => {
dispatch(decrease());
}
return (
<div className="container">
//적용
<h1>{`Count: ${state}`}</h1>
<div>
<button onClick={plusNum}>+</button>
<button onClick={minusNum}>-</button>
</div>
</div>
);
}
📗 Provider
//index.js
import { Provider } from 'react-redux';
import { store } from './Store';
root.render(
<Provider store={store}>
<App />
</Provider>
);
📗 store 생성
//Store/index.js
import { legacy_createStore as createStore } from 'redux';
import { counterReducer } from '../Reducers';
export const store = createStore(counterReducer);
📗 Reducers
//Reducers/initialState.js
export const initialState = 1;
//Reducers/index.js
import { initialState } from './initialState.js';
import { INCREASE, DECREASE } from '../Actions';
export const counterReducer = (state = initialState, action) => {
switch (action.type) {
case INCREASE:
return state + 1;
case DECREASE:
return state - 1;
default:
return state;
}
};
📗 Actions
//Actions/index.js
export const INCREASE = 'INCREASE';
export const DECREASE = 'DECREASE';
export const increase = () => {
return {
type: INCREASE,
};
};
export const decrease = () => {
return {
type: DECREASE,
};
};
📗 Dispatch
//App.js
import { useSelector, useDispatch } from 'react-redux';
import { increase, decrease } from './Actions';
export default function App() {
const dispatch = useDispatch();
const state = useSelector((state) => state);
const plusNum = () => {
dispatch(increase());
};
const minusNum = () => {
dispatch(decrease());
};
return (
<div className="container">
<h1>{`Count: ${state}`}</h1>
<div>
<button onClick={plusNum}>+</button>
<button onClick={minusNum}>-</button>
</div>
</div>
);
}
React Redux Tutorial for Beginners
In-Depth Overview
코드스테이츠 교과서