简体   繁体   English

在 state object 中使用扩展 (...) 运算符实现所需结果的问题

[英]Problems achieving required result of using the spread (...) operator with state object

I have a pimRegistration state initialization as shown in the chrome redux-devtools screen capture below.我有一个 pimRegistration state 初始化,如下面的 chrome redux-devtools 屏幕截图所示。 The nesting being referenced is pimRegistration ( state.domain.patient ):被引用的嵌套是pimRegistration ( state.domain.patient ):

在此处输入图像描述

I updated the patient.name object with the following spread operator statement:我用以下扩展运算符语句更新了patient.name object:

store.update((state) => ({
  ...state,
  ...patientPath,
  ...{ [property]: value },
}));

...where property is the "name" property of the patient object with value . ...其中property是患者 object 的“姓名”属性, value After the update, the following screenshot shows the new state:更新后,以下截图显示了新的 state:

新的更新状态 - 屏幕截图中的黄色

Note that the original patient object (purple in the screenshot) is updated with the name object, duplicated and placed at the root of the state (yellow in screenshot).请注意,原始患者 object(屏幕截图中的紫色)更新为名称 object,复制并放置在 state(屏幕截图中的黄色)的根目录下。

I would like to overwrite the properties of the pimRegistration(state).domain.patient object, not to create a new patient object.我想覆盖pimRegistration(state).domain.patient .domain.patient object 的属性,而不是创建新患者 object。

The state update is called as shown below.调用 state 更新如下所示。

store.update((state) => ({
  ...state,
  ...patientPath, // state.domain.patient
  ...{ [property]: value },
}));

I have tried my different combinations without achieving the desired result.我尝试了不同的组合,但没有达到预期的效果。


The complete update function is shown below.完整的更新 function 如下所示。

update(property: string, path: string, value: any) {
  const paths: string[] = path.split(".");

  const pathReducer = (state: IRegistrationState, path_: string) => {
    if (paths.length <= 0) {
      return state.domain;
    }
    return state[path_];
  };

  const domainPath = state.domain;
  let patientPath, nokPath, referrerPath;

  if (path.includes("patient")) {
    patientPath = paths.reduce(pathReducer, state);
  }

  if (path.includes("nok")) {
    nokPath = paths.reduce(pathReducer, state);
  }

  if (path.includes("referrer")) {
    referrerPath = paths.reduce(pathReducer, state);
  }

  store.update((state) => ({
    ...state,
    ...patientPath,
    ...{ [property]: value },
  }));
}

The function above is invoked with the following statement in Angular 2.上面的function在Angular 2中用下面的语句调用。

if (this.path.includes("patient")) {
  this._repo.update("name", "domain.patient", this.name);
}

Thanks谢谢

Deep updates to a store can be tricky.对商店进行深度更新可能很棘手。 In your function you seem to be spreading the updates at the root rather than at the level you want the update at.在您的 function 中,您似乎在根目录而不是您希望更新的级别传播更新。 This answer here outlines the usual practice to update the state. In short, something like This answer here概述了更新state的通常做法。简而言之,就像

const newState = {
  ...state,
  domain: {
    ...state.domain,
    patient: {
      ...state.domain.patient,
      [property]: value
    }
  }
}

Dynamically passing a path and updating this state can be… cumbersome.动态传递路径并更新此 state 可能……很麻烦。 There are libraries that can help you do it such as immer , but you can possibly hack your way around with normal JS/TS.有一些库可以帮助你做到这一点,比如immer ,但你可能会用普通的 JS/TS 来解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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