首页 > 解决方案 > 更新反应状态而不覆盖先前的状态

问题描述

我正在尝试使用多维数组更新状态值,但我似乎无法弄清楚如何更新其中一个数组对象键值而不影响我在调度调用之后的过程中稍后使用的先前状态值。有效负载下方的代码带有一组 id(节点),我循环遍历并更改状态对象中的唯一对象。相当直截了当,但是更新对象的多维数组而不影响状态让我感到困惑。


    UPDATE_RESTRICTION: (curState, payload) => {
    
      const updatedNodes = {...curState.layout}
      const accessProfile = BpUAE.accessProfileID
    
      payload.nodes.forEach((node, index) => {
    
    
        if (typeof (updatedNodes[node].settings.bp_uae_restrictions) === 'undefined') {
          updatedNodes[node].settings.bp_uae_restrictions = {};
        }
    
        if (typeof (updatedNodes[node].settings.bp_uae_restrictions[accessProfile]) === 'undefined') {
          updatedNodes[node].settings.bp_uae_restrictions[accessProfile] = {};
        }
    
    
        updatedNodes[node].settings.bp_uae_restrictions[accessProfile].is_node_restricted =  JSON.parse(payload.isRestricted);

       })

    
      return {layout: updatedNodes}
    
    
    }

如果您需要更多信息,请告诉我,并感谢您提供的任何帮助。

标签: arraysreactjsstatedispatchpayload

解决方案


您没有正确应用不可变更新模式,您正在改变指向当前状态对象的嵌套引用。您需要创建新的对象引用并浅拷贝所有正在更新的状态。

UPDATE_RESTRICTION: (curState, payload) => {
  const updatedNodes = { ...curState.layout }
  const accessProfile = BpUAE.accessProfileID;

  payload.nodes.forEach((node, index) => {
    if (typeof (updatedNodes[node].settings.bp_uae_restrictions) === 'undefined') {
      updatedNodes[node] = {
        ...updatedNodes[node],
        settings: {
          ...updatedNodes[node].settings,
          bp_uae_restrictions: {},
        },
      };
    }

    if (typeof (updatedNodes[node].settings.bp_uae_restrictions[accessProfile]) === 'undefined') {
      updatedNodes[node] = {
        ...updatedNodes[node],
        settings: {
          ...updatedNodes[node].settings,
          bp_uae_restrictions: {
            ...updatedNodes[node].settings.bp_uae_restrictions,
            [accessProfile]: {},
          },
        },
      };
    }

    // now all the new references have been created and previous
    // state shallow copied, you can update the deeply nested 
    // `is_node_restricted` property.
    updatedNodes[node].settings.bp_uae_restrictions[accessProfile].is_node_restricted = JSON.parse(payload.isRestricted);
  });

  return {
    ...curState,
    layout: updatedNodes,
  };
}

更新:添加了最后一个不可变模式

  const updatedNodes = { ...curState.layout }
  const accessProfile = BpUAE.accessProfileID;

  payload.nodes.forEach((node, index) => {
    if (typeof (updatedNodes[node].settings.bp_uae_restrictions) === 'undefined') {
      updatedNodes[node] = {
        ...updatedNodes[node],
        settings: {
          ...updatedNodes[node].settings,
          bp_uae_restrictions: {},
        },
      };
    }

    if (typeof (updatedNodes[node].settings.bp_uae_restrictions[accessProfile]) === 'undefined') {
      updatedNodes[node] = {
        ...updatedNodes[node],
        settings: {
          ...updatedNodes[node].settings,
          bp_uae_restrictions: {
            ...updatedNodes[node].settings.bp_uae_restrictions,
            [accessProfile]: {},
          },
        },
      };
    }

    // now all the new references have been created and previous
    // state shallow copied, you can update the deeply nested 
    // `is_node_restricted` property.
    updatedNodes[node] = {
      ...updatedNodes[node],
      settings: {
        ...updatedNodes[node].settings,
        bp_uae_restrictions: {
          ...updatedNodes[node].settings.bp_uae_restrictions,
          [accessProfile]: {
            ...updatedNodes[node].settings.bp_uae_restrictions[accessProfile],
            is_node_restricted:  JSON.parse(payload.isRestricted)
          },
        },
      },
    };
  });

  return {
    ...curState,
    layout: updatedNodes,
  };
}```


推荐阅读