更新Redux存储中的数组中的嵌套对象

时间:2019-04-30 09:09:27

标签: javascript reactjs redux

因此,我一直在努力寻找最佳实践,在不直接更改商店的情况下更换商店。尤其是当它嵌套时。

我已经看过一些很棒的文章,但是我仍然无法弄清楚如何在我的场景中做到这一点。 (https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns

在我的情况下,我有一个proposalsrecords的存储,每个记录(proposal)包含一个checklist,它是一个看起来像这样的数组:

checklist: [
    {
      label: 'lease_sign',
      done: false
    }
],

我想将done更改为true。 现在,我的WebSocket触发了此操作:

case CHECK_TODO_ITEM: {
    const { data } = action;

    // find match record
    const proposal = _.find(state.records, ['uuid', data.proposal]);
    // find match check
    const check = _.find(proposal.checklist, ['label', data.item]);
    // change check to true
    check.done = true;

    // find index of propsal in the current state
    const index = _.findIndex(state.records, (p) => p.uuid === data.proposal);

    // re-asign state
    return _.assign({}, state, {
        records: _.assign({}, state.records, {
            [index]: proposal,
        }),
    });
}

我也尝试过:

return {
    ...state,
        records: {
            ...state.records,
            [index]: {
                ...state.records[index],
                checklist,
            }
        }
    }
};

但是,这仍然使州偏离了路线。我不知道实现此目的的完美方法是什么。

如果有人可以帮助我,那就太好了!

3 个答案:

答案 0 :(得分:0)

对我来说,更新不可变状态的最佳库是immutability-helper

使用此代码,您可以执行以下操作(如果可行,可以执行idk,但您有主意):

template <- system.file(package = "officer", "doc_examples/example.docx")
img.file <- file.path( R.home("doc"), "html", "logo.jpg" )
doc <- read_docx(path = template)
doc <- headers_replace_img_at_bkm(x = doc, bookmark = "bmk_header",
                                  value = external_img(src = img.file, width = .53, height = .7))
doc <- footers_replace_img_at_bkm(x = doc, bookmark = "bmk_footer",
                                  value = external_img(src = img.file, width = .53, height = .7))
print(doc, target = tempfile(fileext = ".docx"))

答案 1 :(得分:0)

只需如下使用map并为该对象扩展运算符。 map...都是不可变操作。

const checklist = [
  { id: 1, done: false },
  { id: 2, done: false },
  { id: 3, done: false }
]

const setDone = id => checklist.map(item => (
  id === item.id ? {...item, done: true } : item
))

console.log(setDone(2));

对于清单项目,请使用一些动态生成的唯一ID,并在切换时使用此ID引用相应的状态项目。

答案 2 :(得分:0)

对象是在ECMAScript中由引用分配的,而不是由 value 分配的。

通过使用下划线的find方法,您的proposalcheck变量仍将引用de Redux存储中的对象,然后您可以直接对其进行修改。 您要做的是在您的动作触发化简器的那一刻“克隆”状态或所需状态的一部分。 实现克隆有多种方法:

  • 扩展运算符:newState = {...state}
  • newState = JSON.parse(JSON.stringify(state))
  • 使用lodash(因为您已经在使用它):newState = _.cloneDeep(state)

然后可以修改此新状态,然后将其设置为商店。