【问题标题】:Can somebody help me in understanding what is happening in this piece of code有人可以帮助我理解这段代码中发生了什么吗
【发布时间】:2020-11-03 09:31:25
【问题描述】:

我无法遵循这段代码中的设置状态方法。

    locked: Array(5).fill(false), ///<<<  THIS IS THE INITIAL STATE

     this.setState(st => ({   //<<<<<  SETTING THE STATE ON BUTTON CLICK
      locked: [
        ...st.locked.slice(0, idx),
        !st.locked[idx], // << Iam not able to follow this line and the line after it.
        ...st.locked.slice(idx + 1)
      ]

【问题讨论】:

  • 反转 locked 中位置 idx 的布尔值。
  • 如果写成 this.setState(st =&gt; ({ locked: st.locked.map((el, i) =&gt; i !== idx ? el : !el)})); 可能会更有意义或更容易阅读,当映射索引等于指定索引 idx 时,它只是切换数组中的布尔值。
  • @Drew Reese 是的,这更容易理解和理解。在我正在学习的课程中,这段代码非常混乱且难以理解。非常感谢。

标签: javascript reactjs slice


【解决方案1】:
//locked is a state property with an array value of 5 false booleans
locked: Array(5).fill(false)

//passing current state through a function
this.setState(st => ({ 
  //selecting locked property of state to update
  locked: [
    //making a copy of all indexes up to the index that is to be updated
    ...st.locked.slice(0, idx),
    //toggling the selected index to have a value of true (if previously false)
    !st.locked[idx], 
    //making a copy of all indexes after the index that is to be updated
    ...st.locked.slice(idx + 1)
    ]
}))

【讨论】:

    【解决方案2】:

    你好,我在这段代码上试过了,现在我清楚了。

        const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
        console.log(animals.slice(0, 2));
        console.log(animals[2] = "New Item Bro")
        console.log(animals.slice(2  + 1));
        console.log(animals) 
    

    【讨论】:

      【解决方案3】:

      locked 是一个布尔数组。此代码使用扩展语法从当前布尔值创建一个新的布尔数组,但 idx 的一个元素被反转。详细分类:

      this.setState(st => ({              // callback version of setState that receives the current state as the argument
          locked: [                       // set a new array for `locked` that consists of :
              ...st.locked.slice(0, idx), // every element before the element at idx
              !st.locked[idx],            // the element at idx but inverted
              ...st.locked.slice(idx + 1) // every element after idx
          ]
      

      您还可以创建原始数组的副本,然后在 idx 处反转元素:

      this.setState(st => {
          const locked = Array.from(st.locked);
          locked[idx] = !locked[idx];
          return {locked};
      });
      

      或者你可以映射数组:

      this.setState(st => ({
          locked: st.locked.map((item, i) => i === idx ? !item : item)
      }));
      

      所有这些都解决了在创建新数组时反转idx 处的元素的问题(反应状态不能改变)。

      【讨论】:

      • OP 缺少关于她/他正在处理的代码的一些内容。除非有理由将其内容与先前存在的内容进行比较,否则没有任何人会费尽心思将其作为包含所有这些额外代码的新数组返回。
      • @joshstrike 你将如何更新处于反应状态的数组?当然,您也可以创建该数组的副本,然后在 idx 处反转元素。但是你必须为 locked 创建一个新数组,因为反应状态不应该被改变。
      • 相同。我不使用 React,但在任何绑定结构中都是一样的。我要指出的是,原始代码肯定是在尝试更新模型视图的本地副本,并对其进行比较(可能是为了删除或有限更新)......而不仅仅是简单的 javascript 来翻转布尔值数组中的某处。我们在说同样的话。此代码用于比较并可能从原始代码中删除元素。
      • @joshstrike 我明白了。是的,您可以在不知道反应状态如何详细工作的情况下这么想。我通常也会尝试了解代码背后的意图以避免XY Problem。但在这种情况下,只是 react 需要你创建一个浅拷贝。
      • 在这种情况下,有点不清楚 XY 问题是什么,因为如果你没有注意到这篇文章中的 reactjs 标签,发帖者完全有可能不知道x=!x 的语法。但是,是的。从广义上看,有人不遗余力地创建浅拷贝可能不是最糟糕的事情?嗯。所以。我永远不知道我将要介入什么 ;) 几乎每个 MVC 都需要明确以避免竞争条件,他们只是把它放在不同的地方。
      【解决方案4】:

      如果不了解idx 的来源,它就没有完全的意义。但它会获取 st.locked 数组中的所有内容并保持不变,除了 idx,它会反转。

      然后它返回一个包含这些元素的新数组,这一定是有意完成的。否则,目标 st.locked[idx] 会更简单。 这段代码的作者返回一个新数组是有原因的,这可能很重要。

      【讨论】:

      • 这是一个处于反应状态的数组,无论如何您都必须返回一个全新的数组引用,这总是需要浅拷贝现有数组,否则会被认为是状态突变,这是不好的。
      • 啊。好的 - 我当时认为这是“为什么这个家伙面临的问题不仅仅是改变一个数组”并且没有意识到(a)它是 React——不是我的场景——并且(b)React 不想要你这样做是因为它实际上并不是双向观察对象突变和区分它们,它必须是轮询或只是从后端获取稍后的输入,或者其他什么。无论如何,我自己滚动,这是不使用它的一个很好的理由。我刚刚认识到这种模式是不应该在不理解它是故意创建第二个浅拷贝的情况下被弄乱的。
      • 在这里留下这个答案,因为它没有错,只是一个不使用 React 但在大型项目库中将其作为普通 JS 阅读的人的见解。
      【解决方案5】:

      它只是否定了idx位置的项目。

      它是怎么做到的??

      首先,它从locked 复制idx 之前的所有元素并将其粘贴回locked 中,并带有下一行。

      this.setState(st => ({ 
         locked: [ ...st.locked.slice(0, idx)]
      }));
      

      然后它否定idx位置的项目。

      !st.locked[idx]
      

      然后将其余项目复制回数组中。

      ...st.locked.slice(idx + 1)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-04
        • 1970-01-01
        • 2015-07-14
        相关资源
        最近更新 更多