I'm getting an error here when I add a moment
import moment from "moment";
const filtersDefaultState = {
text: "",
sortBy: "date",
startDate: moment().startOf("month"),
endDate: moment().endOf("month"),
};
so I solve this by adding defaultMiddlewareConfig to my configurestore.js file
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;
};
after that, the code works fine until using DateRangePicker returns an error
react_devtools_backend.js:2655 A non-serializable value was detected in an action, in the path: startDate. Value and A non-serializable value was detected in an action, in the path: endDate. Value
also if I added toISOString(true) to moment it's retruns an error
import moment from "moment";
const filtersDefaultState = {
text: "",
sortBy: "date",
startDate: moment().startOf("month").toISOString(true),
endDate: moment().endOf("month").toISOString(true),
};
Uncaught TypeError: startDate.isSameOrBefore is not a function and Uncaught TypeError: endDate.isSameOrAfter is not a function
import moment from "moment";
export default (expenses, { text, sortBy, startDate, endDate }) => {
return expenses
.filter((expense) => {
const creadtedAtMoment = moment(expense.creadtedAt);
const startDateMatch = startDate
? startDate.isSameOrBefore(creadtedAtMoment, "day")
: true;
const endDateMatch = endDate
? endDate.isSameOrAfter(creadtedAtMoment, "day")
: true;
const textMatch = expense.description
.toLowerCase()
.includes(text.toLowerCase());
return startDateMatch && endDateMatch && textMatch;
})
.sort((a, b) => {
if (sortBy === "date") {
return a.createdAt < b.createdAt ? 1 : -1;
} else if (sortBy === "amount") {
return a.amount < b.amount ? 1 : -1;
}
});
};
in this file I'm using DateRangePicker
import React from "react";
import { DateRangePicker } from "react-dates";
import { connect } from "react-redux";
import {
setEndDate,
setStartDate,
setTextFilter,
sortByAmount,
sortByDate,
} from "../actions/filters";
class ExpenseListfilters extends React.Component {
state = {
calenderFocuesd: null,
};
onDatesChange = ({ startDate, endDate }) => {
this.props.dispatch(setStartDate(startDate));
this.props.dispatch(setEndDate(endDate));
};
onFocusChange = (calenderFocuesd) => {
this.setState(() => ({ calenderFocuesd }));
};
render() {
return (
<div>
<input
text="text"
value={this.props.filters.text}
onChange={(e) => {
this.props.dispatch(setTextFilter(e.target.value));
}}
/>
<select
value={this.props.filters.sortBy}
onChange={(e) => {
if (e.target.value === "date") {
this.props.dispatch(sortByDate());
} else if (e.target.value) {
this.props.dispatch(sortByAmount());
}
}}
>
<option value="date">Date</option>
<option value="amount">Amount</option>
</select>
<DateRangePicker
startDate={this.props.filters.startDate}
endDate={this.props.filters.endDate}
onDatesChange={this.onDatesChange}
focusedInput={this.state.calenderFocuesd}
onFocusChange={this.onFocusChange}
showClearDates={true}
numberOfMonths={1}
isOutsideRange={() => false}
startDateId="MyDatePickerStart"
endDateId="MyDatePickerEnd"
/>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
filters: state.filters,
};
};
export default connect(mapStateToProps)(ExpenseListfilters);
As I mentioned above I tried these solutions but can't solve other problems
If you are stringifying the
momentjsdatetime objects to be stored in the store, then they should be converted back tomomentjsdatetime objects for the UI if that's what it needs.Example:
The change handler will likely also need to again stringify the datetime objects when dispatched to the store.
If you like/prefer you can instead do this conversion in the action creators: