NGRX - 如何通过reducer更新数组中对象中的字段?
Posted
技术标签:
【中文标题】NGRX - 如何通过reducer更新数组中对象中的字段?【英文标题】:NGRX - How to update a field in an object in an array by reducer? 【发布时间】:2020-03-26 05:24:51 【问题描述】:如何通过 reducer 更新数组中的字段?我试过这个:
const customers = state.filteredCustomers;
for (const customer of customers)
for (const addr of customer.addresses)
addr.selected = false;
return
...state,
filteredCustomers: customers,
;
但是它会抛出一个错误:
TypeError: Cannot assign to read only property 'selected' of object '[object Object]'
最好的方法是什么?
【问题讨论】:
【参考方案1】:您可以使用 map 返回具有更新值的新客户数组。
return
...state,
filteredCustomers: customers.map(customer =>
// Either use a second map or another loop
for (const addr of customer.addresses)
addr.selected = false;
return customer;
)
;
【讨论】:
addr.selected = false;
又不行了!甚至用过地图。【参考方案2】:
错误似乎是一些不可变的引用发生了变异。我会尝试这样的事情。
const customers = state.filteredCustomers;
const updatedCustomers = customers.map( customer => (
...customer, addresses: customer.addresses.map( address => ( ...address, selected: false
));
return
...state,
filteredCustomers: ...state.filteredCustomers, ...updatedCustomers ,
;
【讨论】:
【参考方案3】:您必须复制该州的每个级别。在这里,更新 x 层深度的嵌套状态可能会变得很尴尬。这就是为什么我会鼓励normalizing your state。
基本上,您必须遍历客户并复制属性,接下来您必须对地址执行相同操作并将 selected 设置为 false。
return
...state,
filteredCustomers: state.filteredCustomers.map(c => (
...c,
addresses: c.adresses.map(a => (...a, selected: false)
)
;
第二种选择是使用 immer,Clean NgRx reducers using Immer
有一个库可以为 NgRx 8 中的 createReducer
函数执行此操作 - https://github.com/timdeschryver/ngrx-etc/#mutableon。通过这种方法,您可以使用问题中发布的代码 sn-p。
【讨论】:
但我的状态是一个类实例的数组。这使它们成为没有任何方法的对象【参考方案4】:import _ from 'lodash';
并在您的代码中使用
const tags: IAreaTag[] = _.cloneDeep(department.tags);
然后返回常量
所以在你的代码中
const customers = _.cloneDeep(state.filteredCustomers);
【讨论】:
以上是关于NGRX - 如何通过reducer更新数组中对象中的字段?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 ngrx 存储中获取数据并将其更新到 Observable 变量中?
在 @ngrx/store 4.0 中提供 root reducer