I have built a modal component with Redux and Redux toolkit. This is how the component looks
initialState:
const initialsState = { isOpen: false };
export default initialState;
slice:
const modalSlice = createSlice({
name: "modal",
initialState,
reducers: {
setIsOpen: (state, action) => {
state.isOpen = action.payload;
}
}
})
export const { setIsOpen } = modalSlice.actions;
export default modalSliuce.reducer;
selector:
const modal = (state: RootState) => state.modal;
export const modalSelector = createSelector(
modal,
(state) => state.isOpen
);
The modal component itself is quite simple. is just a fixed div with a background and children as props.
I need to use the same modal component for multiple cases with different content, but I'm unsure how to associate each button with the correct modal. When I click on a button, it always opens the first modal instead of the one associated with that button. How can I ensure that each button opens the intended modal?
Instead of a single boolean state value that all modals are referencing you should store discrete state for any modal reference that is being toggled.
Example:
Modal slice
export const initialsState = {
isOpen: {}
};
const modalSlice = createSlice({
name: "modal",
initialState,
reducers: {
setIsOpen: (state, action) => {
state.isOpen[action.payload.id] = action.payload.isOpen;
}
}
})
export const { setIsOpen } = modalSlice.actions;
export default modalSlice.reducer;
Selectors
Update/modify the selector to take an extra parameter, a modal id value in this case.
const modalSelector = (state: RootState) => state.modal;
const isOpenSelector = createSelector(
[modalSelector],
(modal) => modal.isOpen,
);
export const modalIsOpenSelector = createSelector(
[isOpenSelector, (state, id) => id],
(isOpen, id) => isOpen[id]
);
To toggle a specific modal's isOpen
value, dispatch the setIsOpen
action with a modal id and open status.
dispatch(setIsOpen({
id: "modalA",
isOpen: true
}));
dispatch(setIsOpen({
id: "modalA",
isOpen: false
}));
To open a specific modal, use the updated/modified modalIsOpenSelector
function and pass in the modal id parameter.
const isOpen = useSelector(state => modalIsOpenSelector(state, "modalA"));