【问题标题】:Splicing object into array in state with setState update immutability helper使用 setState 更新不变性助手将对象拼接到状态数组中
【发布时间】:2020-04-17 20:27:20
【问题描述】:

我在构建更新助手时遇到问题,想知道是否有人知道如何设置它。我的状态是这样的:

state = {
        array: [
            {
                1: { thing1: 'thing1', thing2: 'thing2' },
            },
            {
                2: { thing1: 'thing1', thing2: 'thing2' },
            },
            {
                3: { thing1: 'thing1', thing2: 'thing2' },
            }
        ]
};

我想要获取一个对象并用它替换数组中的特定位置。所以传统上看起来像这样的东西:

const newObj = {
     newthing1: 'newthing1',
     newthing2: 'newthing2'
};

state.array.splice(0, 1, newObj);

现在使用 immutability-helper,当我尝试使用索引位置更新它时,我收到一个错误,即 prevState.array 不可迭代。有什么想法吗?

我的 setState 函数看起来像:

this.setState((prevState) => ({
                array: update(...prevState.array[1], {$splice: { 2: { newthing1: 'newthing1' }}})
            }))

谢谢!

【问题讨论】:

  • 为什么在 prevState.array[1] 内部更新之前使用扩展运算符?它以数组源为第一个参数
  • 另外拼接上的语法也不正确,它需要一个数组数组来表示要拼接的值

标签: javascript reactjs setstate


【解决方案1】:

我不确定这是否是您想要做的,因为您的 setState 示例看起来使用的值与您原来的 .splice 不同。但我以你原来的拼接为例:

供参考:https://reactjs.org/docs/update.html#nested-collections

    state = {
            array: [
                {
                    1: { thing1: 'thing1', thing2: 'thing2' },
                },
                {
                    2: { thing1: 'thing1', thing2: 'thing2' },
                },
                {
                    3: { thing1: 'thing1', thing2: 'thing2' },
                }
            ]
    };

    const newObj = {
      newthing1: 'newthing1',
      newthing2: 'newthing2'
    };
    this.setState( prevState =>
      update(prevState, { array: { $splice: [[0, 1, newObj]] } })
    );

老实说,这看起来不对,因为对象不一致。我猜你的意思是:

update(prevState, { array: { $splice: [[0, 1, {1: newObj}]] } })

或者,如果我在 update 上放弃你的尝试,也许是这样?:

update(prevState, { array: { $splice: [[1, 1, {2: newObj}]] } })

解释它的作用:
prevState对象开始,
首先它遍历属性array
然后它遍历splice 命令列表(本例中只有 1 个)
执行此拼接:

 [
   1, // starting index to splice at
   1, // length to splice out
   {2: newObj} // object(s) to insert
 ]

【讨论】:

  • 是的,抱歉 - 我原来的问题在再次查看后感到困惑。忽略newObj 并离开我的状态结构。我想用该索引处的全新对象简单地替换数组 [0] 或数组 [1] 或任何我需要的东西。所以可以说我在数组中的原始对象是{ 1: { thing: 'thing' }}。我想用{1: { anotherThing: 'anotherThing' }} 替换它。这有意义吗?
  • 如果它是一个对象,它将是{1: { $set: { anotherThing: 'anotherThing' } }。如果是数组,应该是 { $splice: [[1, 1, {anotherThing: 'anotherThing'} ]]
  • 有趣的是它的说法 prevState 没有定义。这也在 onChange 函数中。应该是这样的吧? this.setState((prevState) => ({ update(prevState, { array: { $splice: [[0, 1, { 1: newObj } ]]}}) }))?
  • 差不多this.setState((prevState) => update(prevState, { array: { $splice: [[0, 1, { 1: newObj } ]]}} ))
  • x => ({ obj: 1}) 等同于(function(x) { return {obj: 1} }).bind(this),括号是一种小懒人的技巧,使其将括号解析为对象表示法而不是函数闭包括号
【解决方案2】:

为什么不只使用本机方法。

state = {
  array: [
      {
          1: { thing1: 'thing1', thing2: 'thing2' },
      },
      {
          2: { thing1: 'thing1', thing2: 'thing2' },
      },
      {
          3: { thing1: 'thing1', thing2: 'thing2' },
      }
  ]
};
const newObj = {
  newthing1: 'newthing1',
  newthing2: 'newthing2'
};
const index = 1 // could be any id

const newState = {array: state.array.slice(0, index).concat({[index]: newObj}).concat(state.array.slice(index+1))}
console.log(newState)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 2019-05-31
    • 1970-01-01
    • 2017-06-16
    • 2020-02-19
    • 1970-01-01
    • 2015-09-03
    相关资源
    最近更新 更多