토이 프로젝트 II를 진행하면서 각 페이지에서 쓰이는 모달 상태관리를 Redux를 사용하여 전역으로 상태관리를 할 수 있게 modalSlice를 만들었다.
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface ModalState {
modals: { [key: string]: boolean };
}
const initialState: ModalState = {
modals: {},
};
export const modalSlice = createSlice({
name: 'modal',
initialState,
reducers: {
showModal: (state, action: PayloadAction<string>) => {
state.modals[action.payload] = true;
},
hiddenModal: (state, action: PayloadAction<string>) => {
state.modals[action.payload] = false;
},
},
});
export const { showModal, hiddenModal } = modalSlice.actions;
export default modalSlice.reducer;
initialState modals는 각 모달의 상태를 객체로 관리하고 모달의 고유한 모달명을 modals의 키로 사용한다.
modalSlice의 리듀서는 모달의 고유한 모달명을 받아 해당 모달을 보여주고 숨겨주는 역할을 한다.
import { configureStore } from '@reduxjs/toolkit';
import modalSlice from './Reducers/ModalSlice.ts';
const store = configureStore({
reducer: {
modal: modalSlice,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
만든 modalSlice는 store에 등록하고 최상위 경로에 Provider를 두고 store에 등록된 리듀서를 내려준다.
import { useDispatch, useSelector } from 'react-redux';
.
.
const dispatch: AppDispatch = useDispatch();
const yesNoModal = useSelector((state: RootState) => state.modal.modals['yesNoModal']);
const spacificationModal = useSelector((state: RootState) => state.modal.modals['spacificationModal']);
.
.
.
const onYesNoModal = () => {
yesNoModal ? dispatch(hiddenModal('yesNoModal')) : dispatch(showModal('yesNoModal'));
};
const onSpacificationModal = () => {
spacificationModal ? dispatch(hiddenModal('spacificationModal')) : dispatch(showModal('spacificationModal'));
};
.
.
.
useSelector를 사용하여 각각의 모달의 모달명을 선언하고 useDispatch로 모달을 보여주고 숨기는 리듀서를 실행한다.
boolean값으로 상태관리 되고있는 각각의 모달들을 modalSlice를 사용하여 전역으로 관리할 수 있게 되었다.