【问题标题】:Redux Reducer how to update normalized state childrenRedux Reducer 如何更新标准化状态子节点
【发布时间】:2017-09-22 16:32:45
【问题描述】:

我有一个有效载荷 A,它代表一个 n 深的嵌套树,它看起来像..(你可以将 section 数组视为树上的子节点)

const data = {
  id: 123,
  sections: [{
    id: 1,
    sections:[{ id: 4, sections: [ { id: 5, sections: [] } ] }]
  }, {
    id: 2,
    sections:[]
  }, {
    id: 3,
    sections:[]
  }]
};

payload A 的标准化状态如下所示

    {
  "entities": {
    "sections": {
      "1": { "id": 1, "sections": [ 4 ] },
      "2": { "id": 2, "sections": [] }, 
      "3": { "id": 3, "sections": [] },
      "4": { "id": 4, "sections": [ 5 ] },
      "5": { "id": 5, "sections": [] }
    },
    "menu": {
      "123": { "id": 123, "sections": [ 1, 2, 3 ] }
    }
  },
  "result": 123
}

如果用户要扩展第 5 节,我会离开并从服务器加载更多子项。标准化后从服务器返回的有效负载 B 如下所示

{
  "entities": {
    "sections": {
      “6”: { "id": 6, "sections": [] }, 
    },
    "menu": {
      "1234”: { "id": 1234, "sections": [ 6 ] }
    }
  },
  "result": 1234
}

我如何编写一个 reducer 来组合(合并/映射等)规范化有效负载 A 和规范化有效负载 B,以便新的 Redux 存储状态如下所示...

    {
  "entities": {
    "sections": {
      "1": { "id": 1, "sections": [ 4 ] },
      "2": { "id": 2, "sections": [] }, 
      "3": { "id": 3, "sections": [] },
      "4": { "id": 4, "sections": [ 5 ] },
      "5": { "id": 5, "sections": [6] },
    “6”: { "id": 6, "sections": [] }
    },
    "menu": {
      "123": { "id": 123, "sections": [ 1, 2, 3 ] }
    }
  },
  "result": 123
}

【问题讨论】:

    标签: javascript reactjs redux normalizr


    【解决方案1】:

    这应该不难实现,在你的 reducer 中,我确信你会保持之前的状态,以下列方式从之前的状态 entities.sections 中提取值

    var newData = {...state.entities.sections,newSectionPayload}

    newSectionPayload 应该包含新扩展部分的数据。

    我没有尝试过,但我很确定它应该可以工作。

    【讨论】:

      【解决方案2】:

      这是我解决上述问题的减速器,它似乎可以解决问题

      export const productHierarchyReducer: ActionReducer<ProductHierarchyState> = (state:any={}, action: Action) => {
         switch (action.type) {
              case ADD_PRODUCTHIERARCHY:
                   const normalizedTreeNodes = normalize(action.payload, TreeNodesSchema);          
                   return normalizedTreeNodes; 
               case ADD_PRODUCTHIERARCHY_CHILDREN:
      
                         const {targetNodeId, payload} = action.payload;
                         const normalizedChildNodes = normalize(payload, TreeNodesSchema);   
      
                         const expandTargetNode=dotProp.set(
                              state, 
                               `entities.children.${targetNodeId}.expanded`, 
                                  expanded => true
                              );
      
                           const updatedWithNewChildren = dotProp.set(
                              expandTargetNode, 
                               `entities.children.${targetNodeId}.children`, 
                                  children => 
                                  children.concat(normalizedChildNodes.entities.nodes[normalizedChildNodes.result].children)
                              );
      
                           const newState=dotProp.set(updatedWithNewChildren, 
                               `entities.children`,
                                 children =>  Object.assign({}, children, normalizedChildNodes.entities.children) 
                               )   
      
                         return newState;
      
              default:
                  return state;
          }    
      };
      export const ProductHierarchyReducer = {
          productHierarchy: productHierarchyReducer
      }
      

      TreeNodesSchema 也如下所示。

      const nodeKey = new schema.Entity('children')
      const children = new schema.Array(nodeKey);
      nodeKey.define({ children });
      export const TreeNodesSchema = new schema.Entity('nodes', { children });
      

      dotProp.set() 语法属于 dot-prop-immutable https://github.com/debitoor/dot-prop-immutable

      这个关于更新标准化状态的资源很有用 http://redux.js.org/docs/recipes/reducers/UpdatingNormalizedData.html

      【讨论】:

        猜你喜欢
        • 2019-07-28
        • 2023-03-16
        • 2018-08-04
        • 1970-01-01
        • 2021-01-08
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2019-07-05
        相关资源
        最近更新 更多