当值相等时,React Hooks useState setValue仍会重新渲染一次

时间:2019-08-26 05:24:31

标签: javascript reactjs frontend react-hooks

我下面有示例代码:

function App() {
  console.log("render");
  const [val, setVal] = React.useState(0);
  return (
    <div className="App">
      <h1>{val}</h1>
      <button onClick={() => setVal(12)}>Update with same value</button>
    </div>
  );
}

当我多次单击一个按钮时,控制台会记录3次“ render”消息。对我来说,应该只有2次:

  • 1用于首次渲染

  • 2表示从val 0到12的更新(单击按钮时)

自此以来,它不应重新渲染,因为相同的值(12)已更新为val。

但是为什么会出现3次?这意味着尽管更新了相同的值,它仍然需要重新渲染一次。

认识的人请先解释一下。

P / S:我发现,仅当值更改然后使用相同的值进行更新时,它才会引起额外的重新渲染

function App() {
  console.log("render");
  const [val, setVal] = useState(4);
  return (
    <div className="App">
      <h1>{val}</h1>
      <button onClick={() => {
        setVal(val => val + 1)
      }}>Update</button>
      <button onClick={() => {
        setVal(val => val)
      }}>Update with same value</button>
    </div>
  );
}

第一次单击第二个按钮时,没有重新渲染呼叫,但是如果您单击第一个按钮然后第二个按钮,则第二个按钮会导致1次额外的重新渲染

3 个答案:

答案 0 :(得分:3)

React无法猜测render()的输出不会改变:它必须再次render()并将结果与​​先前的render()比较。

然后魔术发生了:如果没有差异,则不会更新DOM;如果存在差异,它会尝试仅根据需要创建/销毁元素,因为这是昂贵的部分,而不是运行render()-不应这样做。

更改状态通常会触发对render()的调用(不一定是DOM修改),但是如果要控制该行为,请定义shouldComponentUpdate


注意:这适用于非挂钩组件。但是,我不知道 hooks 的行为与常规组件的行为略有不同:似乎您正确地期望setState不会在值保持不变-请参见Yash Joshi的答案。

答案 1 :(得分:2)

此主题可能会帮助您:CursorMoved

此外,您可以在React: Re-Rendering on Setting State - Hooks vs. this.setState上查看第二段内容:

  

请注意,React可能仍需要再次渲染该特定组件,然后才能发布。不必担心,因为React不会不必要地“深入”到树中。如果渲染时要进行昂贵的计算,则可以使用useMemo对其进行优化。

答案 2 :(得分:-1)

美好的一天!尝试这样做:

function App() {
  console.log("render");
  const [val, setVal] = React.useState(0);
  const valHandler = (value) => {
    setVal(value)
  }
  return (
    <div className="App">
      <h1>{val}</h1>
      <button onClick={valHandler(12)}>Update with same value</button>
    </div>
  );
}