问题是为什么组件会渲染,尽管新状态等于先前状态(浅比较)
// On second button click
const prevState = data
// State trigger
setFoo(data)
// Same state, it doesn't triggers a render
data === prevState
因此,该组件不会因状态更改而触发渲染。
But 这是由于另一个原因而发生的,如 Hooks API 下的文档“字里行间”中所述摆脱状态更新部分:
尽管在某些情况下,React 可能仍然需要在跳过子组件之前调用您的组件,但它不应该影响您的代码(反应.dev).
请注意,React 可能仍需要在退出之前再次渲染该特定组件(遗产.reactjs.org).
与类组件不同,对于函数组件,设置后相同状态就像我们的例子一样,有时,React 将需要另一个渲染来验证其相等性。它不幸的边缘情况.
但它不应该将你视为“性能问题”,因为它不会影响React.Node
树,它不会继续在和解如果状态没有改变,则继续处理。它甚至不会进行不必要的钩子调用。
另一个简化的例子
这里同样如此,还有另一个用于保释的渲染,另一个“A”日志。
尽管有“保释”渲染,但请注意useEffect
不运行。
import React, { useEffect } from "react";
import ReactDOM from "react-dom";
const App = () => {
const [state, setState] = React.useState(0);
useEffect(() => {
console.log("B");
});
console.log("A");
return (
<>
<h1>{state}</h1>
<button onClick={() => setState(42)}>Click</button>
</>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
如果您想知道日志顺序(“为什么‘A’在‘B’之前记录?”),请尝试深入研究另一个问题:React useEffect深入/使用useEffect?