【问题标题】:Merge a nested subset object into deeply nested state in React在 React 中将嵌套的子集对象合并到深度嵌套的状态
【发布时间】:2019-08-31 14:13:06
【问题描述】:

我从一个函数返回的新数据是一个我想与我的状态合并的新块。

我用一些虚拟数据做了一个jsbin 示例:

https://jsbin.com/kufonikica/1/edit?js,console

这是我的状态对象:

const state = {
  group: {
    Everything: {
      teams: [
        {
          title: "dev",
          id: "dev",
          member: [
            {
              title: "John doe",
              id: "adsfadsfqwerewqv"
            }
          ]
        },
        {
          title: "test",
          id: "test",
          member: [
            {
              title: "Jack",
              id: "3242ewrewr"
            }
          ]
        },
        {
          title: "sleep",
          id: "sleep",
          member: [
            {
              title: "Homer Simpson",
              id: "sadfasdfdsaf3"
            },
            {
              title: "John",
              id: "sadfasddddfdsa"
            }
          ]
        }
      ],
      title: "Everything is cool",
      key: "Everything"
    },
    Something: {
      teams: [
        {
          title: "dev",
          id: "dev",
          member: [
            {
              title: "Susan",
              id: "dsafadsf"
            }
          ]
        }
      ],
      title: "Something is cool",
      key: "Something"
    }
  }
};

现在,当发生变化时,我会收到teams 的新子集。例如,一个新的块看起来像:

const updatedSubsetState = {
  teams: [
    {
      title: "dev",
      id: "dev",
      member: [
        {
          title: "John doe",
          id: "adsfadsfqwerewqv"
        }
      ]
    },
    {
      title: "test",
      id: "test",
      member: [
        {
          title: "Jack",
          id: "3242ewrewr"
        }
      ]
    },
    {
      title: "sleep",
      id: "sleep",
      member: [
        {
          title: "Homer Simpson",
          id: "sadfasdfdsaf3"
        },
        {
          title: "John+++IS NOW UPDATED+++",
          id: "sadfasddddfdsa"
        }
      ]
    }
  ]
};

我也知道应该更新的主群:const whichThingShouldUpdate = 'Everything'

使用updatedSubsetState 中的更新行合并这两个对象以获得全新状态的正确方法是什么:"John+++IS NOW UPDATED+++" 这意味着生成的对象应如下所示:

const state = {
  group: {
    Everything: {
      teams: [
        {
          title: "dev",
          id: "dev",
          member: [
            {
              title: "John doe",
              id: "adsfadsfqwerewqv"
            }
          ]
        },
        {
          title: "test",
          id: "test",
          member: [
            {
              title: "Jack",
              id: "3242ewrewr"
            }
          ]
        },
        {
          title: "sleep",
          id: "sleep",
          member: [
            {
              title: "Homer Simpson",
              id: "sadfasdfdsaf3"
            },
            {
              title: "John+++IS NOW UPDATED+++",
              id: "sadfasddddfdsa"
            }
          ]
        }
      ],
      title: "Everything is cool",
      key: "Everything"
    },
    Something: {
      teams: [
        {
          title: "dev",
          id: "dev",
          member: [
            {
              title: "Susan",
              id: "dsafadsf"
            }
          ]
        }
      ],
      title: "Something is cool",
      key: "Something"
    }
  }
};

【问题讨论】:

  • 您需要将 state.group.everything.teams[x].member 中的项目与 updatedSubsetState.teams[x].members 合并还是用 updatedSubsetState.teams[x].members 替换它?
  • @HMR 我认为——如果我理解正确的话——子集可以完全替换旧状态。我更新了问题以更好地说明这一点。
  • updatedSubsetState 是否只有一个 teams 属性,或者是否有其他属性要替换 state.group.Everything
  • 不,它只有团队属性,只知道更新的团队属性...

标签: javascript reactjs object


【解决方案1】:

您可以继续使用我在您的other question 中提到的 setStatePath。使用 lodash set 比较困难,因为它不接受回调作为值。

所以你可以这样做:

reduceStatePath(
  state,
  ['group', 'Everything','teams'],
  () => updatedSubsetState.teams
),

如果updatedSubsetState 有多个键或者teams 键是动态的,您可以这样做:

Object.entries(updatedSubsetState).reduce(
  (state, [key, value]) =>
    reduceStatePath(
      state,
      ['group', 'Everything'].concat(key),
      () => value
    ),
  state
)

【讨论】:

  • 我得到一个修饰符不是一个函数。我的函数调用如下所示: this.setState( reduceStatePath( this.state, [ 'group', 'Everything', 'teams', teamsIndex, 'skills', SkillsIndex, 'changed', ], ['group', Everything , 'teams'], () => updatedSubsetState.teams ), );
  • 那么您传递给 reduceStatePath 的第三个参数不是函数。
  • 更新了评论。第三个参数是() => draggedData.lanes
  • 我很确定这不是因为错误实际上是 modifier is not a function 并且 reduceState 接收到一个名为 modifier 的参数,它希望它是一个函数。也许你可以给我一个包含一些代码的 pastebin 链接?
  • @Kalaschnik 因为setState是异步的,如果你想记录它你需要使用callback
猜你喜欢
  • 2023-03-09
  • 2017-08-27
  • 2019-04-28
  • 2020-01-07
  • 2019-04-03
  • 1970-01-01
  • 2012-08-29
  • 1970-01-01
  • 2021-10-06
相关资源
最近更新 更多