🗃️ Redux 제대로 이해하기 - Store, Action, Reducer, Dispatch
리액트에서 상태 관리는 기본적으로 props를 통해 이루어진다. 하지만 애플리케이션이 커지고 컴포넌트가 많아질수록 상태를 여러 컴포넌트에서 공유하거나 깊게 전달해야 하는 상황이 발생하면서 코드가 복잡해질 수 있다.
이러한 문제를 해결하고 상태 관리를 보다 체계적이고 예측 가능하게 하기 위해 등장한 것이 Redux이다. 애플리케이션의 모든 상태를 하나의 중앙 저장소(store)에 보관하고 상태를 변경할 때에는 반드시 액션(action)과 리듀서(reducer)를 통해 변경한다.
이러한 구조 덕분에 상태 변화의 흐름이 명확하고 디버깅이 쉬워지며 규모가 큰 프로젝트에서도 일관된 방식으로 상태를 관리할 수 있다.
# Redux의 핵심 구성요소
Redux는 3가지 핵심 구성요소로 동작한다.
- Store
- Action
Reducer
그리고 이 구성요소들을 연결해 주는 역할을 하는 것이 바로 Dispatch이다.
1. Store
Store는 앱의 전체 상태(state)를 보관하는 객체로써 하나의 앱에 하나의 store가 존재하고 이 store는 모든 컴포넌트가 공유한다.
createStore()로 생성한다.
import { createStore, combineReducers } from "redux";
import { counterReducer } from './counterReducer';
const rootReducer = combineReducers({
counter: counterReducer
});
export const store = createStore(rootReducer);
이후 Provider로 App 컴포넌트를 감싸준다.
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<Counter />
</Provider>
);
Provider는 리액트 컴포넌트 트리 전체에 Redux의 store를 전달하는 역할을 하며 내부의 모든 컴포넌트들이 Redux 상태에 접근할 수 있게 만들어준다.
2. Action
Action은 상태 변경이 필요하다는 요청을 전달하는 객체이다. 항상 type이라는 필수 속성을 가지며 상황에 따라 payload 같은 추가 데이터도 포함할 수 있다.
const incrementAction = {
type: 'INCREMENT',
payload: 1
};
3. Reducer
Reducer는 현재 상태와 액션을 받아서 새로운 상태 객체를 반환하는 함수이다. 상태를 직접 수정하지 않고 항상 새로운 상태 반환함으로써 상태 변경을 관리한다.
const counterReducer = (state = { value: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { value: state.value + action.payload };
default:
return state;
}
};
4. Dispatch
Dispatch는 액션을 리듀서에 전달해서 상태를 변경하도록 하는 함수이다. 컴포넌트 내부에서 dispatch()를 호출하면 해당 액션이 실행되어 리듀서로 전달되고 그에 따라 상태가 업데이트된다.
import { useDispatch, useSelector } from "react-redux";
const Counter = () => {
const dispatch = useDispatch();
const count = useSelector((state) => state.counter.value);
const incrementAction = {
type: 'INCREMENT',
payload: 1
};
const handleClick = () => {
dispatch(incrementAction);
};
return (
<div>
<p>카운트: {count}</p>
<button onClick={handleClick}>+1 증가</button>
</div>
);
};
export default Counter;