Search code examples
reactjsexpressredux-toolkit

redux-toolkit -> non-serializable value detected


Error:

index.js:1 A non-serializable value was detected in an action, in the path: payload.config.transformRequest.0.

Value: ƒ

transformRequest(data, headers) {

normalizeHeaderName(headers, 'Accept');
normalizeHeaderName(headers, 'Content-Type');

if (utils.isFormData(data) || utils.isArrayBuffer(data) || utils.i…

Slice:

export const getProducts = createAsyncThunk(
    'products/getProducts', 
    async() => {
        const res = await axios.get('http://localhost:5000/products/view-products', {withCredentials: true});
        return res;
    }
)

const getProductsSlice = createSlice({
    name : 'products',
    initialState : {
        list : [],
        status : null
    },
    extraReducers : {
        [getProducts.pending] : (state) => {
            state.status = 'loading'
        },
        [getProducts.fulfilled] : (state, {payload}) => {
            console.log("produtcts payload: ", payload.data)
            state.list = payload.data
            state.status = 'success'
        },
        [getProducts.rejected] : (state) => {
            state.status = 'failed'
        }
    }
})

Inside Component:

const dispatch = useDispatch();
    const data = useSelector(state => state.products.list);
    console.log("the products are :", data);

    useEffect(() => {
        dispatch(getProducts());
    }, [dispatch]);

Other slices in the app work fine. Having a hard time working around the non-serializable


Solution

  • The problem with returning the result of axios.get as it is, is that apart from data it contains various other fields related to the request, including config for which you got the error. Although you're only saving data and not config, as the whole res object passes to the store it goes through a middleware called Serializability, which is included in redux-toolkit and enforces Redux recommendation to only store serializable data.

    Serializable means it can be written down as text and converted back to original object without losing information, which doesn't work with functions. A javascript function apart from code also have scope (memory associated to it), which cannot be represented as text.

    Serializability checks the whole payload (it is executed before your data reaches the store, so it doesn't know which parts will be used) and notices config. As config has methods among its members Serializability alerts you that it is not serializable. You could switch the middleware off, but it can detect genuine issues, so it's generally a better idea to just keep only relevant data in the payload.