更新嵌套状态,一成不变

时间:2019-08-13 07:10:30

标签: javascript reactjs

在我的React应用程序中,我有一个名为parameters的对象,它表示一棵树。

这是我的parameters对象:

{
    "Access_List": {
        "state": "override",
        "value": {
            "88": {
                "state": "inherit",
                "value": [{
                    "ip": {
                        "state": "inherit",
                        "value": "19.1.1.1"
                    },
                    "mask": {
                        "state": "override",
                        "value": "0.0.0.0"
                    }
                }]
            }
        }
    }
}

我想要一种更新树下所有叶子值的通用方法。我该如何实现?例如,我要更新ip中的值。

我知道我可以递归地遍历parameters对象,并为每个节点提供一个键,该键代表它在树中的路径。例如,ip将是

"ip":{
        "state":"inherit",
        "value":"19.1.1.1",
        "key":"Access_List.value.88.value.0.ip"  
}

然后,我可以使用lodash deepClone函数对状态进行深层复制,然后使用lodash set如下更改ip的值:

set(parameters, `${key}.value`, NEW_VALUE)

,最后设置新状态。

这种方式将导致我所有的孩子重新渲染。如何知道对象的路径,一成不变地更新状态。

2 个答案:

答案 0 :(得分:0)

我认为您看错了。不变性是关于不只更改对象的一部分。那是正确的方法。您可能需要的是一种防止不必要的重新渲染的方法。您可以使用PureComponent或通过自己实现shouldComponentUpdate来实现这一点-取决于您对parameters对象的使用。要考虑的另一件事是,您是否真的需要将一个对象中的所有内容都通过应用程序传递。

答案 1 :(得分:0)

我建议使用类似immerimmutability-helper的名称。这使您可以轻松更新不可变的嵌套对象。

要沉浸其中,您可以这样写:

produce(yourObject, objectState => {
       objectState.Access_List.value.88.value[0].ip.value = 0
});

对于不变性帮助者:

update(yourObject, {
     Access_List: {
         value: {
             88: {
                 value: {
                    [0]: {
                        ip: {
                           value :{$set: 0}
                       }
                 }
             }
         }
     }
});

这些是更新对象并保持不变的好方法,可以极大地提高性能。两者都返回新的,不变的更新对象。 它只会更新您要更新的路径,而将您不想更新的这些对象保留为相同的路径。

如果您使用redux,mobx或纯函数/组件,这将防止不必要的重新渲染,因为仅会渲染使用对象更新部分的组件。

希望这会有所帮助。编码愉快。

相关问题