4

I'm starting to learn React + hooks. I'm on useReducer right now. But I'm having problem to update my useReducer state. every time I want to update 1 field on my object state, all other fields will get deleted.

My solution is to pass them all the existing values, even though I only need to update 1 field. Is there more efficient way of doing this?

Here is my solution:


const initialState = {
    filter: {
        text: "Filter",
        list: [],
        isActive: false,
        message: "",
    },
    apiList: []
};

const reducer = (state, action) => {
  switch (action.type) {
    case "SET_FILTER_LIST":
      return {
        ...state,
        filter: { ...state.filter,
            list: action.payload.list,
            isActive: action.payload.isActive,
            message: action.payload.message,
            text: action.payload.text,
        }
      };

    default:
      return state;
  }
};
//BELOW - I just want to pass the e.target.textContent to text field. To avoid deleting the other fields. I re-pass all the existing value so it wont get deleted.

  const onSelect = e => {
      let filter = e.target.textContent;

      dispatch({
        type: 'SET_FILTER_LIST',
        payload: {
            list: state.filter.list,
            text: filter,
            message: state.filter.message,
            isActive: state.filter.isActive
        }
      });
  };

Makopa
  • 91
  • 9

2 Answers2

2

You can use the next code:

return {
    ...state,
    filter: {
        ...state.filter,
        ...action.payload,
    }
};
Alexander
  • 1,220
  • 6
  • 12
  • @Makopa it seems like this is correct answer. Always appreciate the one who helped you by upvotes and selecting the best answer. – Zohaib Ijaz Feb 06 '20 at 14:40
  • this solve my problem!! its seems that I dont fully understand the spread operator! thanks man!! hi @ZohaibIjaz sorry for waiting for my upvote. i just tested it Today. and it works perfectly! awesome! – Makopa Feb 07 '20 at 05:31
  • @Makopa It's not my answer but just asking to select the correct answer. – Zohaib Ijaz Feb 07 '20 at 07:52
0

If I understand you, you already have the answer somewhat:

return {
    ...state,
    filter: {
        ...state.filter,
        text: action.payload
    }
}

then only pass the text field into the payload

KieranLewin
  • 1,780
  • 2
  • 7
  • 13
  • hello this will overwrite other fields if i dont pass value to other fields which dont need updating – Makopa Feb 07 '20 at 05:33