Home > OS >  state gets different values in react redux
state gets different values in react redux

Time:11-14

the title may be misleading but here is what happened:
reducer.js:

// initial state
const initialState = {
  notes: [
    {
      content: "reducer defines how redux store works",
      important: true,
      id: 1,
    },
    {
      content: "state of store can contain any data",
      important: false,
      id: 2,
    },
  ],
  filter: "IMPORTANT",
};

// reducer
const noteReducer = (state = initialState, action) => {
  switch (action.type) {
    case "NEW_NOTE":
      console.log("state", state);
      return state.notes.concat(action.data); 
// ...
}

const generateId = () => Math.floor(Math.random() * 1000000);

// action
export const createNote = (content) => {
  return {
    type: "NEW_NOTE",
    data: {
      content,
      important: false,
      id: generateId(),
    },
  };
};

in index.js:

const reducer = combineReducers({
  notes: noteReducer,
  filter: filterReducer,
});

const store = createStore(reducer, composeWithDevTools());

//dispatch a note from index.js
//it works here
store.dispatch(
  createNote("combineReducers forms one reducer from many simple reducers")
);

returns in the console.log("state", state); in reducer.js:

state 
{notes: Array(2), filter: 'IMPORTANT'}
filter: "IMPORTANT" // 'filter' is here
notes: (2) [{…}, {…}]
[[Prototype]]: Object //prototype is object

Here createNote is successful.
However, when creating a new note through:

const NewNote = (props) => {
  const dispatch = useDispatch();
  const addNote = (event) => {
    event.preventDefault();
    const content = event.target.note.value;
    event.target.note.value = "";
// createNote does not work here
    dispatch(createNote(content));
  };

  return (
    <form onSubmit={addNote}>
      <input name="note" />
      <button type="submit">add</button>
    </form>
  );
};

Here the console.log("state", state); returns:

state 
(3) [{…}, {…}, {…}]
0: {content: 'reducer defines how redux store works', important: true, id: 1}
1: {content: 'state of store can contain any data', important: false, id: 2}
2: {content: 'combineReducers forms one reducer from many simple reducers', important: false, id: 824517}
length: 3
// 'filter' is missing
[[Prototype]]: Array(0) // state prototype changed to array

In which the filter is gone from the state, so the creation is not successful.
In short, store.dispatch( createNote("...") ); works but not dispatch(createNote(content));.
The reason seems to be that noteReducer received different states. But in both cases filter is not specified.
I wonder why this happens and how to solve it?

CodePudding user response:

as we know when you are using a reducer the reducer takes 2 parameters one for initial stat and the other for action. any action will be run in the reducer you need to save the old state
by used spread operator {...state}

case "NEW_NOTE": console.log("state", state); {...state, notes: state.notes.concat(action.data)}

CodePudding user response:

found the issue.
noteReducer should be:

const noteReducer = (state = initialState, action) => {
  switch (action.type) {
    case "NEW_NOTE":
      return { ...state, notes: state.notes.concat(action.data) };
//...
}

just found out that above is a wrong fix. the right one is actually is:

const noteReducer = (state = initialState.notes, action) => {

otherwise noteReducer is changing the filter as well. but it should be changing the 'note' part only.

  • Related