리덕스(Redux)란 리액트에서 가장 사용률이 높은 상태관리 라이브러리입니다.
리액트 컴포넌트들의 상태 로직들이나 글로벌 상태 관리를 손쉽게 해줄 수 있습니다.
리덕스는 Action, Reducer, Store, View로 구성된 하나의 패턴이다.
이러한 일련의 과정을 통해 상태를 다루게 된다.
{
type: "ADD_HELLO",
text: "Hello World"
}
export const addHello = text => ({
type: "ADD_HELLO",
text
})
const counter = (state,action) => {
switch(action.type) {
case 'INCREASE':
return state + 1;
case 'DECREASE':
return state - 1;
default:
return state;
}
}
/* Ducks 패턴 액션 타입 */
const SET_DIFF = 'counter/SET_DIFF';
const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASE';
/* 액션 생성 함수 만들기 */
export const setDiff = diff => ({ type: SET_DIFF, diff });
export const increase = () => ({ type: INCREASE });
export const decrease = () => ({ type: DECREASE });
/* 초기 상태 선언 */
const initialState = {
number: 0,
diff: 1
};
/* 리듀서 선언 */
export default function counter(state = initialState, action) {
switch (action.type) {
case SET_DIFF:
return {
...state,
diff: action.diff
};
case INCREASE:
return {
...state,
number: state.number + state.diff
};
case DECREASE:
return {
...state,
number: state.number - state.diff
};
default:
return state;
}
}
const store = createStore(rootReducer);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
function CounterContainer() {
// useSelector는 리덕스 스토어의 상태를 조회하는 Hook입니다.
// state의 값은 store.getState() 함수를 호출했을 때 나타나는 결과물과 동일합니다.
const { number, diff } = useSelector(state => ({
number: state.counter.number,
diff: state.counter.diff
}), shallowEqual);
// useDispatch 는 리덕스 스토어의 dispatch 를 함수에서 사용 할 수 있게 해주는 Hook 입니다.
const dispatch = useDispatch();
// 각 액션들을 디스패치하는 함수들을 만드세요
const onIncrease = () => dispatch(increase());
const onDecrease = () => dispatch(decrease());
const onSetDiff = diff => dispatch(setDiff(diff));
return (
<Counter
// 상태와
number={number}
diff={diff}
// 액션을 디스패치 하는 함수들을 props로 넣어줍니다.
onIncrease={onIncrease}
onDecrease={onDecrease}
onSetDiff={onSetDiff}
/>
);
}
export default CounterContainer;
// 각 컴포넌트는 서로 다른 파일입니다.
const Counter = ({ number, diff, onIncrease, onDecrease, onSetDiff }) => {
const onChange = e => {
onSetDiff(parseInt(e.target.value, 10));
};
return (
<div>
<h1>
{number}
</h1>
<div>
<input type="number" value={diff} min="1" onChange={onChange} />
<button onClick={onIncrease}>+</button>
<button onClick={onDecrease}>-</button>
</div>
</div>
)
}
export default Counter;