【问题标题】:Understanding React's setState method理解 React 的 setState 方法
【发布时间】:2021-09-24 16:09:53
【问题描述】:

我了解以下代码将一个新对象添加到对象数组中,但在特定语法上很模糊:setProductList([array, obj])

据我所见,setProductList 函数接受一个对象。该对象由一个数组和一个对象组成。那么它是如何将对象添加到数组中的呢?这是内置在 JS 还是 React 中的?

// array of products
const Products = [
  {
    item: "basketball",
    price: 3,
    description: "basketball desc",
  },
  {
    item: "football",
    price: 5,
    description: "football desc",
  },
];

// setting state
const [productList, setProductList] = useState(Products);

// handling click
const handleClick = () => {
   // Don't quite understand the syntax of below block
   setProductList([
      ...productList, // spread creates a copy of the array
      {
        item: "baseball",
        price: 4,
        description: "baseball desc",
      },
    ]);
  };

【问题讨论】:

  • That object consists of an array and an object 不,它由对象数组组成

标签: javascript reactjs setstate


【解决方案1】:

你看到的是Spread operator (...)

对象或数组中的所有元素都需要包含在某种列表中时,可以使用扩展语法

通过编写[ (element inside) ],您确实创建了一个新数组。 ...productList 单独不会创建新数组

你可以理解...productList,因为它可以帮助你编写更短的代码,而不是像这样写

setProductList([
  productList[0],
  productList[1],
  // ...
  productList[productList.length - 1],
  {
    item: "baseball",
    price: 4,
    description: "baseball desc",
  },
])

另一个可以帮助您理解扩展运算符的示例是Math.max 的使用。基本上,Math.max 的语法是Math.max(value0, value1, ... , valueN)

例如你有一个包含 N 个元素的数组,因为 Math.max 不能单独将数组作为参数,所以要计算数组的最大值,你可以迭代每个元素并进行比较

const arr = [1, 3, 2]
let max = -Infinity

for (const num of arr) {
  max = Math.max(max, num)
}

console.log(max)

但是现在使用扩展运算符,您可以用更短的方式获得相同的结果

const arr = [1, 3, 2]
let max = Math.max(...arr)

console.log(max)

【讨论】:

    【解决方案2】:

    这个功能内置在js里面,叫Object Spreading

    例子

    var x = [1, 2] // an array
    
    console.log(x)
    
    // spreads an array, and put an extra element
    var y = [...x, 6]
    
    console.log(y)

    所以,state hook returns a function here - setProductList 这只是将状态更新为新数组。

    这是一种常见的做法。请参阅此detailed answer 以获得详细说明

    【讨论】:

      【解决方案3】:

      好的,你不理解的代码基本上是设置当前数组的新副本,但包括新元素(这就像在数组中推送一个新元素。但是推送会修改原始数组. 在这种情况下,它正在制作副本并将值推送到该新数组)

      让我们逐行进行。 我们有:

       setProductList([
            ...productList,
            {
              item: "baseball",
              price: 4,
              description: "baseball desc",
            },
          ]);
      

      我们将定义:

       setProductList([                       // Line 0
            ...productList,                   // Line 1
            {                                 // Line 2
              item: "baseball",               // Part of Line 2
              price: 4,                       // Part of Line 2
              description: "baseball desc",   // Part of Line 2
            },                                // Part of Line 2
          ]);                                 // Part of Line 1(]) & 0())
      

      【讨论】:

        【解决方案4】:

        我猜你的困惑来自于不理解spread syntax

        Spread in array literals

        更强大的数组字面量

        不使用展开语法,使用现有数组创建新数组 作为其中的一部分,数组字面量语法已经不够用了 并且必须使用命令式代码,而不是使用以下组合 push()splice()concat() 等。 语法变得更加简洁:

        let parts = ['shoulders', 'knees'];
        let lyrics = ['head', ...parts, 'and', 'toes'];
        //  ["head", "shoulders", "knees", "and", "toes"]
        

        就像参数列表的展开一样,... 可以在 数组字面量,并且可以多次使用。

        查看您的代码时:

        setProductList([
          ...productList, // spread creates a copy of the array
          {
            item: "baseball",
            price: 4,
            description: "baseball desc",
          },
        ]);
        

        语句“spread 创建数组的副本” 不正确。扩展运算符本身不会创建副本。它获取可迭代项(如数组)中的项目,并将它们作为单独的参数/元素放置在上下文中。

        [...productList]
        

        上面会创建一个副本,因为我们定义了一个新数组并将productList 的所有项目放在这个新数组中。从而创建一个副本。

        [...productList, newItem]
        

        定义一个新数组,将productList 的所有项放在这个新数组中,并将newItem 放在它后面。由于我们添加了newItem,因此严格来说并不是真正的副本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-08-24
          • 2023-03-29
          • 2014-11-17
          • 1970-01-01
          • 2021-12-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多