1
votes

I am using react-redux (for the first time). I have a component into which users put a 'startDate' and an 'endDate'. These should then be stored in the redux store, so that they persist.

I have the following action creator:

export const setDates = dates => ({
  type: "SET_DATES",
  payload: dates
});

The following reducer:

const dates = (state = {}, action) => {
  switch (action.type) {
    case "SET_DATES":
      return action.payload;
    default:
      return state;
  }
};

export default dates;

The state is set conditionally (i.e. only if the start and end dates actually make sense) like this:

  handleSubmit = () => {
    if (this.state.startDate <= this.state.endDate) {
      store.dispatch(setDates([this.state.startDate, this.state.endDate]));
      window.location = `/search/${
        this.state.location
      }&${this.state.startDate.format("DDMMYYYY")}&${this.state.endDate.format(
        "DDMMYYYY"
      )}&${this.state.guestCount}&${this.state.offset}&${this.state.count}`;
    } else {
      console.log("HANDLE ERROR");
    }
  };

The problem, according to the chrome redux dev-tools, is that when the submit is triggered, the store does indeed change to the new dates, but it then seems to be immediately overwritten to the empty state. By modifying the reducer to take state = {dates: 'foo'} as its first argument, I can get the store to persist 'dates:foo'. This suggests to me that, for some reason, the reducer is being called twice - once with an action of type "SET_DATES", which works, and then again, immediately, with an action of unknown type (confirmed by console.log-ging action.type), which causes it to return the default state.

So I'm pretty sure I know what the problem is, but I have no idea why it would do this.

2
Could you please provide an example of what you expect state to be after setDates is executed - Arman Charan
May be the change of window location causes the problem - benchpresser
is the page reloading after you doing window.location=...? - Murali Krishna
@MuraliKrishna Yes, the page does reload, but I thought the whole point of the redux state was that it persisted... - Alex
@ArmanCharan I would expect it to be: { 'dates': [startDate, endDate], } Where startDate and endDate are actually moment.js objects - Alex

2 Answers

1
votes

I Already commented, but anyways. The problem is that you reload the page. It reloads redux, and it boots up from initial state, which is probably an empty array. Here is a great video from one of the brains behind redux.

https://egghead.io/lessons/javascript-redux-persisting-the-state-to-the-local-storage

It all boils down to subscribing to the store state changes, and saving it / loading the state back from storage of your choise.

0
votes

Try changing you reducer like this

const dates = (state = {}, action) => {
  switch (action.type) {
    case "SET_DATES":
      return Object.assign({}, state, {
        action.payload
      });
    default:
      return state;
  }
};

export default dates;