繁体   English   中英

逐点更新单个值,不突变和重建对象的初始结构 JS

[英]Update single value by point at it, without mutation and reconstructing object's initial structure JS

我正在寻找一种更好地组织我的动作/减速器的方法,现在它看起来像这样:

[SOME_ACTION]: state => ({
    ...state,
    isModified: true,
    orders: {
        ...state.orders
        // or maybe change something here
    },
    documentation: {
        ... state.documentation
       // or maybe change something here
    }
})

问题是 object 有很深的嵌套,我必须跟踪它的每一层并相应地在任何地方添加它。 我必须编写所有这些来更新单个值。

我有哪些选择? 现在我只想能够通过指向我想要更改的内容来更新某个嵌套级别的一个/多个值。

您只需复制更改的 object 及其父对象,而不是其子对象。 例如,在您的示例中,我假设更改为isModified: true 您不需要复制ordersdocumentation ,您可以重复使用它们,因为它们没有改变:

[SOME_ACTION]: state => ({
    ...state,
    isModified: true
})

如果您愿意,您可以给自己一个实用程序 function 来进行更改。 例如:

function newState(state, path, value) {
    const result = {...state};
    const lastKey = path[path.length - 1];
    let obj = state;
    for (const key of path.slice(0, path.length - 1)) {
        obj = obj[key];
    }
    obj[lastKey] = value;
    return result;
}

...或类似的(即兴表演)。

在那种特定情况下,它并不是那么有用,因为变化很浅:

[SOME_ACTION]: state => newState(state, ["isModified"], true)

但是如果你有一个改变来使结构更深入:

[SOME_ACTION]: state => newState(state, ["orders", someOrderId, "fulfilled"], true)

...写起来比同等的东西要轻松一些:

[SOME_ACTION]: state => ({
    ..state,
    orders: {
        ...state.orders,
        [someOrderId]: {
            ...state.orders[someOrderId],
            fulfilled: true
        }
    }
})

例子:

 const state = { isModified: false, orders: { "order1": { customer: "Joe Bloggs", fulfilled: false }, "order2": { customer: "Jane Doe", fulfilled: false } }, documentation: { foo: {}, bar: {} } }; const someOrderId = Math.random() < 0.5? "order1": "order2"; const updated = newState(state, ["orders", someOrderId, "fulfilled"], true); console.log(`Updated order '${someOrderId}':`); console.log(updated); function newState(state, path, value) { const result = {...state}; const lastKey = path[path.length - 1]; let obj = state; for (const key of path.slice(0, path.length - 1)) { obj = obj[key]; } obj[lastKey] = value; return result; }

暂无
暂无

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

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