2

I'm building a budget App using React 18 and Redux I don't know what is the problem here

import moment from "moment";

const filtersDefaultState = {
  text: "",
  sortBy: "date",
  startDate: moment().startOf("month"),
  endDate: moment().endOf("month"),
};

I got this problem after adding moment

redux-toolkit.esm.js?8bb3:444 A non-serializable value was detected in the state, in the path

Error Image

Source code on Github: https://github.com/KhaledGharib/budgetApp

Trying to use DateRangePicker from react-dates

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
XED
  • 53
  • 5
  • The problem is that `moment.startOf(..)` and `moment.endOf(..)` return `moment` objects, you'll need to use something like `moment.startOf(..).toDate()` or `moment.startOf(..).format()` (the first one will get you a `Date` object the second one a `String`) – Titus Mar 12 '23 at 18:07
  • Please provide enough code so others can better understand or reproduce the problem. – Community Mar 12 '23 at 20:58

1 Answers1

1

The issue here is that moment.js date objects are not JSON serializable.

You can "serialize", e.g. stringify, the data yourself:

import moment from "moment";

const filtersDefaultState = {
  text: "",
  sortBy: "date",
  startDate: moment().startOf("month").toISOString(true), // "2023-03-01T00:00:00.000Z"
  endDate: moment().endOf("month").toISOString(true),     // "2023-03-31T23:59:59.999Z"
};

You can alternatively decide to exclude this part of state in the serializability check if you really want to store non-serializable objects in the redux store via the serializabilityMiddleware:

import { configureStore, createSlice } from "@reduxjs/toolkit";
import expensesReducer from "../reducers/expenses";
import filtersReducer from "../reducers/filters";

const defaultMiddlewareConfig = {
  serializableCheck: {
    ignoredPaths: ["filters.startDate", "filters.endDate"],
  }
};

export default () => {
  const store = configureStore({
    reducer: {
      expenses: expensesReducer,
      filters: filtersReducer,
    },
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware(defaultMiddlewareConfig),
  });
  return store;
};
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • 1
    the code works fine when I add the changes but I still get the same error message when I choose the date from DateRangePicker. looks like this: A non-serializable value was detected in an action, in the path: `startDate`. Value: Moment {_isAMomentObject: true, _isUTC: false, _pf: {…}, _locale: Locale, _d: Wed Mar 01 2023 12:00:00 GMT+0300 (GMT+03:00), …} Take a look at the logic that dispatched this action: {type: 'setStartDate', startDate: Moment} – XED Mar 13 '23 at 14:35
  • @XED My guess here is that you are dispatching a `momentjs` datetime object to the store, saving it directly into state; this too also should be stringified. You can recreate `momentjs` datetime objects when selecting state back to the UI. Does this make sense? – Drew Reese Mar 13 '23 at 16:29
  • please take a look at [link](https://stackoverflow.com/questions/75726410/erorr-a-non-serializable-value-was-detected-in-the-state-in-the-path-filters) I repost all the errors. I hope this provides enough code to understand the problem – XED Mar 13 '23 at 20:10