在 ReactJS 中使用 useState 时 [...arr, addThisElement] 和 arr.push(addThisElement) 有什么区别?

What is the difference between [...arr, addThisElement], and arr.push(addThisElement) when using useState in ReactJS?

谁能解释一下这两者的区别:

const arr = users;

arr.push({ firstName, email })

setUsers((prevState) => arr)

还有这个:

setUsers(prevState => [...prevState, { firstName, email }])

在第一种情况下,您改变引用 arr 添加用户。在第二种情况下,您创建一个全新的数组,复制旧数组中的所有数据并添加新用户。

你应该使用第二种情况,因为反应使用 Object.is 比较状态,如果你的第一种情况是 return true 因为即使添加了参考也没有改变新用户,因此 ui 不会更新。

答案是引用和对象相等...

Array.prototype.push() 就地改变数组,这意味着它的对象引用不会改变。

const prevState = [1,2,3];
const nextState = prevState;
nextState.push(4);
nextState === prevState; // true

[...prevState, { firstName, email }] 创建一个不等于 prevState.

的新数组
const prevState = [1,2,3];
const nextState = [...prevState, 4];
nextState === prevState; // false

根据 React 的状态变化检测规则...

Bailing out of a dispatch

If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)

使用 .push() 并将状态更新为相同的值意味着 React 将从 re-render 中退出,您将看不到所做的更改。

users.push({
  firstName: "Bob",
  email: "bob@example.com"
});
setUsers(users);

创建一个新数组并使更改可见

setUsers((prev) => [
  ...prev,
  {
    firstName: "Bob",
    email: "bob@example.com"
  }
]);