개요
- redux 연습을 하면서 먼저 가장 간단한 카운터 기능을 구현하였지만, 같은 프로젝트 내에서 배열, 문자열, 객체 등 다른 데이터들도 다뤄보고 싶었다!
- 하나의 파일에 여러
reducer
, action
등을 몰아서 작성하는 방법을 사용 할 수 있지만, 작성하는 김에 컴포넌트 별 action
, reducer
를 나누어 가독성에 좋게 파일구조를 작성해보면 좋을 것 같았다.
- 하지만 그렇게 되면
reducer
가 2개 이상 생기게 되는데, 이 때 어떻게 작성하는 지에 대해 정리해보고자 한다.
새로운 전역상태 만들기
- Array 라는 컴포넌트에 문자열로만 이루어진 간단한 Todo 기능을 만들고, 해당 배열을 전역상태로 만들어 다뤄보려 한다.
types
- 간단하게
추가
, 삭제
, 초기화
세 가지의 기능을 구현하기로 하고, 각각에 맞는 action type 을 지정해주었다.
export const ADD_ELEM = 'ADD_ELEM';
export const REMOVE_ELEM = 'REMOVE_ELEM';
export const CLEAR_ELEM = 'CLEAR_ELEM';
actions
- 추가 및 삭제를 구현하기 위해 인자의 값이 필요했고, 매개변수와 해당 매개변수의 타입을 지정하여 원하는 데이터를 받는다.
- 여기서 지정된 매개변수는
dispatch(action 이름(인자));
을 이용하여 인자의 값을 저장한다.
- 이때,
type
외의 데이터는 payload
에 담아 전달해야한다.
import { ADD_ELEM, REMOVE_ELEM, CLEAR_ELEM } from './types';
export const addElem = (value: string) => {
return {
type: ADD_ELEM,
payload: {
value,
},
};
};
export const removeElem = (idx: number) => {
return {
type: REMOVE_ELEM,
payload: {
idx,
},
};
};
export const clearElem = () => {
return {
type: CLEAR_ELEM,
};
};
reducer
- 해당 컴포넌트에서 사용할 초기 상태 값을 지정하고,
action
이 전달하는 값들의 타입을 지정한다.
→ type
뿐만 아니라, payload
가 전달하는 값들 또한 타입을 지정해줘야한다.
- 이전에 작성한
counterReducer
와 마찬가지로 export
해준다.
import { ADD_ELEM, REMOVE_ELEM, CLEAR_ELEM } from './types';
const initialState = {
arr: ['기본데이터1', '기본테이터 2'],
};
const arrayReducer = (
state = initialState,
action: { type: string; payload: { value: string; idx: number } }
) => {
switch (action.type) {
case ADD_ELEM:
return {
...state.arr,
arr: [...state.arr, action.payload.value],
};
case REMOVE_ELEM:
return {
...state.arr,
arr: state.arr.filter((el, idx) => {
return idx !== action.payload.idx;
}),
};
case CLEAR_ELEM:
return {
...state.arr,
arr: [],
};
default:
return state;
}
};
export default arrayReducer;
store
combineReducers
함수를 이용하여 만들어진 reducer
들을 내보낸다.
combineReducers
- 여러
reducer
들을 하나의 store
에 저장 할 수 있게 해주는 함수이다.
combineReducers
의 첫번째 인자에 객체 형태로 원하는 reducer
를 작성하고, 변수에 저장한다.
- 해당 변수를
createStore
의 인자로 사용하면 다수의 reducer
를 store
로 전달 할 수 있다.
import {
combineReducers,
legacy_createStore as createStore,
} from '@reduxjs/toolkit';
import counterReducer from './counter/reducer';
import arrayReducer from './array/reducer';
const reducer = combineReducers({
counterReducer,
arrayReducer,
});
const store = createStore(reducer);
export default store;
console.log(store.getState());
를 이용하여 전체 상태를 확인 할 수 있으며, 그 출력은 아래와 같다.
{
counterReducer: {…},
arrayReducer: {…}
}
store.getState()
는 store
에 저장된 모든 상태를 반환한다.
- 만약 데이터를 저장하는 상태의 이름을 바꾸고자 하는 경우에는 아래와 같이 작성하면 된다.
const reducer = combineReducers({
data1 : counterReducer,
data2 : arrayReducer,
});
{
data1: {…},
data2: {…}
}
+
- 현재는 컴포넌트 별로 폴더를 만들어
actions
, reducer
를 관리하고 있지만, actions
, reducer
각각 폴더를 만들어 몰아서 관리하는 방법도 고려해보고 연습해봐야겠다!