使用扩展运算符在不同级别上更新状态

时间:2019-03-05 14:21:21

标签: javascript reactjs ecmascript-6 redux

我的reducer状态初始化如下:

state = {
    name: ""
    authenticationObj: {
        userContactInfo: {
            billingAddress: {
                billingCountry: undefined,
                billingAddress1: undefined,
                billingAddress2: undefined,
                billingCity: undefined,
                billingPostalCode: undefined,
                billingPhoneNumber: undefined,
                billingFirstName: undefined,
                billingLastName: undefined,
                billingPersonalEmail: undefined,
                billingSelectedRegion: undefined
            },
        },
        subscriptions: [],
        fullName: "",
        subscriberDefaultPhoneNumber: ""
    }
}

现在我需要使用传播运算符来更新状态,这就是我正在运行的内容:

case SET_SUBSC_LIST:
    state = { ...state,
        authenticationObj: { ...state.authenticationObj,
            subscriptions: action.payload.subscriptions
        }
    }

但是如果我想更新不同级别的属性该怎么办。例如,如果我需要更新订阅,同时还需要更新billingAddress内部的billingAddress1,我该如何实现?

4 个答案:

答案 0 :(得分:2)

您可以使用lodash中的merge方法而不是传播运算符,以便于阅读。

case SET_SUBSC_LIST:
    state = _.merge(state, { authenticationObj: {
            subscriptions: action.payload.subscriptions
        }
    }

答案 1 :(得分:1)

如果要同时更新订阅和billingAddress1,则可以执行以下操作:

    case SET_SUBSC_LIST:
    state = { ...state,
        authenticationObj: { ...state.authenticationObj,
            subscriptions: action.payload.subscriptions,
            userContactInfo:{
                ...state.authenticationObj.userContactInfo,
                billingAddress: {
                    ...state.authenticationObj.userContactInfo.billingAddress,
                    billingAddress1: action.payload.billingAddress1
               }
            }

        }
    }

您需要传播价差,以便维护原始对象,并且仅更改要使用的字段。

答案 2 :(得分:1)

Hamed Minaee,您可以使用传播算子更新不同的字段,但是正如samb102指出的那样,您应该使用setState:

//you can do something like this:
this.setState(prevState => ({ ...prevState,
        authenticationObj: { ...prevState.authenticationObj,
            subscriptions: action.payload.subscriptions,
            userContactInfo: {
                ...prevState.authenticationObj.userContactInfo,
                billingAddress: {
                    ...prevState.authenticationObj.userContactInfo.billingAddress,
                    billingAddress1: "your new state value",
                }
            }
        }
    }))

如您所见,这样做确实很繁琐,所以更好的方法是复制状态并直接更改所需的属性:


const { authenticationObj } = this.state;

authenticationObj.subscriptions = action.payload.subscriptions;
authenticationObj.userContactInfo.billingAddress.billingAddress1 = "your new state value";

this.setState({ authenticationObj: authenticationObj });

答案 3 :(得分:1)

state = {
  ...state,
  authenticationObj: {
    ...state.authenticationObj,
    userContactInfo: {
      ...state.authenticationObj.userContactInfo,
      billingAddress: {
        ...state.authenticationObj.userContactInfo.billingAddress,
        billingAddress1: action.payload.billingAddress1   
      }
    },
    subscriptions: action.payload.subscriptions
  }
};