Redux: 상태 관리를 위한 중앙 저장소
React 앱이 커지면서 컴포넌트 간 상태 공유가 복잡해질 때, Redux를 사용하면 전역 상태를 예측 가능하게 관리할 수 있습니다.
useSelector, useDispatch를 통해 store에 접근합니다.상태를 보관하는 중앙 저장소입니다.
import { createStore } from 'redux';
const store = createStore(reducer);
주의: 상태가 많아질수록 store 구조는 계층적으로 잘 설계해야 합니다.
상태 변경의 의도를 담은 객체입니다.
const addTodo = (text) => ({ type: 'ADD_TODO', payload: text });
type 속성이 있어야 합니다.payload를 포함합니다.예시:
store.dispatch({ type: 'INCREMENT' });
주의: action 타입은 문자열이므로 오타에 주의하거나 action type 상수로 관리하는 것이 좋습니다.
이전 상태와 action을 받아서 새 상태를 반환하는 함수입니다.
const counterReducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
};
import { Provider } from 'react-redux';
import { store } from './store';
<Provider store={store}>
<App />
</Provider>
import { useSelector, useDispatch } from 'react-redux';
const count = useSelector((state) => state.counter);
const dispatch = useDispatch();
<button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
useSelector는 상태를 읽고,useDispatch는 action을 보냅니다.주의: useSelector는 참조 동등성(shallow equal)로 리렌더링 되므로 불필요한 리렌더링 방지를 위해 selector 최적화가 필요할 수 있습니다.
Redux 사용의 보일러플레이트 코드를 줄여주는 공식 도구입니다.
import { configureStore, createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: (state) => state + 1,
decrement: (state) => state - 1,
},
});
export const { increment, decrement } = counterSlice.actions;
export const store = configureStore({
reducer: {
counter: counterSlice.reducer,
},
});
createSlice로 action과 reducer를 한 번에 정의 가능state = state + 1처럼 작성 가능