从React文档中,我了解到,只有在状态值发生变化时,组件才会重新渲染.

例如

import React, { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  console.log("I am rendering");

  const handleButtonClick = () => {
    setCount(0);
  };
  return (
    <>
      <button onClick={handleButtonClick}>Increment</button>
      Count value is: {count}
    </>
  );
}

即使我们点击按钮,消息I am rendering也只打印once,因为setCount功能将值设置为0,这是count的当前值

由于当前值和future 值没有变化,因此该组件不会重新渲染.

意外行为

然而,当我们在setCount(0)之前添加额外的行setCount(1)时,没有观察到类似的行为

import React, { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  console.log("I am rendering");

  const handleButtonClick = () => {
    setCount(1); //this line has been added extra
    setCount(0);
  };
  return (
    <>
      <button onClick={handleButtonClick}>Increment</button>
      Count value is: {count}
    </>
  );
}

原则上,最终count值的输出没有变化.但是,如果我们单击按钮,组件将重新呈现并打印消息I am rendering


我找不到这种行为的解释.这种行为符合预期吗?.

Shouldn't the component re-render only when the final value of the state is different from the current value ?

推荐答案

有时,Reacts需要另一个渲染阶段来决定是否需要救援.顺便说一句,当我们说"救助"意味着救助Reconciliation人的过程.

请注意Bailing out a state update上的文档:

注意react may still need to render that specific component again before bailing out.

下面是这类 case 的另一个例子:

import React, { useEffect } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const [state, setState] = React.useState(0);

  useEffect(() => {
    console.log("B");
  }, [state]);

  console.log("A");

  return (
    <>
      <h1>{state}</h1>
      <button onClick={() => setState(42)}>Click</button>
    </>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));

Edit  React state trigger

您注意到下面的日志(log)及其解释:

A // First render
B // Mount

A // State change from 0 -> 42, triggers render
B // useEffect dep array change, triggers callback

A // **Our issue**, React needs another render

Javascript相关问答推荐

追踪执行顺序

如何使用JavaScript向html元素添加样式

橡皮擦完全让画布变成白色

使用JavaScript单击上一个或下一个特定按钮创建卡滑动器以滑动单个卡

拖放仅通过 Select 上传

将字符串UTC Date转换为ngx—counting leftTime配置值的数字

当点击注册页面上的注册按钮时,邮箱重复

如何将Cookie从服务器发送到用户浏览器

JS—删除对象数组中对象的子对象

您能在卸载程序(QtInsteller框架)上添加WizardPage吗?

提交链接到AJAX数据结果的表单

为什么123[';toString';].long返回1?

确保函数签名中的类型安全:匹配值

如何在JAVASCRIPT中临时删除eventListener?

以编程方式聚焦的链接将被聚焦,但样式不适用

自定义图表工具提示以仅显示Y值

在Vercel中部署Next.js项目时获取`ReferenceError:未定义文档`

通过解构/功能组件接收props-prop验证中缺少错误"

调用特定数组索引时,为什么类型脚本不判断未定义

在高位图中显示每个y轴系列的多个值