繁体   English   中英

我必须在 React 钩子中使用扩展运算符的原因是什么?

[英]What is the reason I have to use spread operator in React hooks?

预期行为

每次点击渲染计数器增加一

实际行为

渲染计数器不会增加,但内部会增加(如警报消息所示)。 看看这个截图: http : //prntscr.com/ujtsu9 (它不会一直发生..)

代码

import React, { Component, useState } from "react";
import "./App.css";

function App(props) {
  const [all, setAll] = useState([{ name: "PHP", votes: 1 }]);

  function changeAll() {
    const newAll = all;
    alert(newAll === all); //alert true

    newAll[0].votes++;
    setAll(newAll);

    alert(all[0].votes);
  }

  return (
    <>
      <div className="voteCount">{all[0].votes}</div>
      <div className="lanugageName">{all[0].name}</div>
      <button onClick={changeAll}>Click Here</button>
    </>
  );
}

export default App;

我尝试过的:

更改行const newAll = all; -> 到 -> const newAll = [...all]; 然后它起作用了。 但是,然后警报说“假”

  • 为什么我需要使用扩展运算符?
  • 如果我使用扩展运算符,为什么newAll === all false ?

为什么我需要使用扩展运算符?

不需要使用扩展语法*,但您确实需要将要变异的现有状态浅复制为新的对象/数组/内存引用。 使用扩展语法是实现此目的的方法之一。 使用数组时,使用许多返回数组的数组函数也很常见,例如 map、filter、slice。

如果我使用扩展运算符 [语法*],为什么newAll === all false ?

当您const newAll = all您也将all状态的引用保存到newAll中,但是您const newAll = [...all]您首先将状态传播到一个新的数组引用中,然后将其保存到newAll

试试看

 const all = [1,2,3]; const newAll1 = all; const newAll2 = [...all]; console.log(newAll1 === all); // true console.log(newAll2 === all); // false

* 传播语法

我还想提醒你不要像这样的模式

newAll[0].votes++;
setAll(newAll);

即使您浅层复制了allnewAll[0].votes++仍会被视为状态突变。 如果您需要更新处于反应状态的数组元素,那么您应该浅复制您打算更新的任何对象的属性。

setAll(all.map((el, index) => !index ? el : { ...el, votes: el.votes + 1 }))

更重要的是,如果任何状态更新取决于现有状态(增加计数是默认示例,顺便说一句),您将希望使用功能更新。

setAll(all => all.map((el, index) => !index ? el : { ...el, votes: el.votes + 1 }))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM