简体   繁体   中英

Updating redux state

I am trying to make my redux reducers more simple when updating state. For example, here is a reducer below:

const initialState = {
  emails: {
    id: {
      emailAddress: null,
      emailBody: null,
      emailSubject: null,
    },
  },
  calls: {},
};

function messaging(state = initialState, action) {
  switch (action.type) {
    case actionTypes.SET_EMAIL_ADDRESS:
      return {
        ...state,
        emails: {
          ...state.emails,
          [action.id]: {
            emailAddress: [action.emailAddress]
          },
        },
      };
    default:
      return state;
  }
}

export default messaging;

I tried writing the reducer below instead, but webstorm is complaining that this is not proper notation. What am I doing wrong? Also, any suggestions on how to update state in a more cleaner fashion is greatly appreciated. Thanks!

case actionTypes.SET_EMAIL_ADDRESS:
  return {
    ...state,
    emails[action.id]: {
      ...state.emails[action.id],
      emailAddress: [action.emailAddress]
    },
  };

You need to enclose the dynamic key inside square brackets.

case actionTypes.SET_EMAIL_ADDRESS:
  return {
    ...state,
    [state.emails[action.id]]: {
      ...state.emails[action.id],
      emailAddress: [action.emailAddress]
    },
  };

Based on your initial state

And to avoid overriding existing values for emailBody and emailSubject .

I would rewrite this way:

case actionTypes.SET_EMAIL_ADDRESS:
    const currentEmails = state.emails;
    const emailId = action.id;
    const emailAddress = action.emailAddress;

    const email = { ...currentEmails[emailId], emailAddress };
    const emails = { ...currentEmails, [emailId]: email };
    return { ...state, emails };

It always pays to use descriptive names!

I've started using immer when reducers need to make changes to deeply nested state. eg..

import produce from "immer";

function messaging(state = initialState, action) {
  switch (action.type) {
    case actionTypes.SET_EMAIL_ADDRESS:
      return produce(state, draft => {
        draft.emails[action.id] = { emailAddress: [action.emailAddress] };
      });
    default:
      return state;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM