I am using Redux Toolkit and I want to store an action creator in state. When I do this, I receive an error regarding non-serializable values in my action as well as my state. Using the code below as an example of my issue, how can I resolve it without just suppressing the warning?
import { ActionCreatorWithoutPayload } from '@reduxjs/toolkit';
export type ModalType =
{
type: 'MyModal';
actionText: string;
onConfirm: ActionCreatorWithoutPayload;
}
type ui = {
modal: ModalType | null;
};
const initialState: ui = {
modal: null
};
export const slice = createSlice({
name: 'ui',
initialState: initialState,
reducers: {
showDialog: (state, action: PayloadAction<ModalType>) => {
state.modal= action.payload;
},
someAction: (state) => {
// do something
},
}
});
import { someAction } from 'reducers/uiSlice';
<Button
onClick={() =>
dispatch(
showDialog({
type: 'MyModal', actionText: `Some text`, onConfirm: someAction}
)
)}
/>
A non-serializable value was detected in an action, in the state: `payload.onConfirm`. Value: ƒ actionCreator() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (prepareAction) {
var prepared = prepareAction.apply(void…
To be honest, this is a bad idea, and really not at all how Redux should be used.
Based on the examples, it looks like you're trying to create a modal and pass in a callback as a prop. There are other ways to do this that will work better with Redux, and in fact a few years ago I wrote a post on Managing Modals and Context Menus with Redux. It shows a few different techniques to do this in a way that is compatible with how Redux should be used.
Today, the option I'd recommend is using a custom middleware that tracks what modals are open, returns a promise from dispatch(showModal())
, and resolves the promise when you do dispatch(closeModal(modalId))
.
The post links to https://github.com/AKolodeev/redux-promising-modals as one option for this. I also have an incomplete but mostly working similar implementation in a gist at https://gist.github.com/markerikson/8cd881db21a7d2a2011de9e317007580 that shows some of the potential approaches.