import React, { useState, useEffect } from "react";
const Foo = () => {
console.log("render foo");
return <div> foo</div>;
};
const App = () => {
const [value, setValue] = useState(1);
useEffect(() => {
console.log("effect", value);
}, [value]);
console.log("rendering");
return (
<div>
{" "}
<Foo /> <button onClick={() => setValue(value)}>Click To Render</button>
</div>
);
};
export default App;
如果将状态挂钩更新为与当前状态相同的值,React将纾困而不渲染子代或发射效果。 (重点是我的) (React使用Object.is比较算法。)
请注意,React可能仍需要再次渲染该特定组件,然后才能发布。不必担心,因为React不会不必要地“深入”到树中。如果渲染时要进行昂贵的计算,则可以使用useMemo优化它们。
在我给出的示例中,我们可以看到useEffect挂钩没有触发,如文档所述,但是我的Foo
组件正在渲染。
这是为什么?
我认为内联函数可能会导致渲染-但是如果我使用useCallback
将其更改为记忆函数,则会发生相同的行为:
const handleClick = useCallback(() => setValue(value), [value]);
console.log("rendering");
return (
<div>
{" "}
<Foo /> <button onClick={handleClick}>Click To Render</button>
</div>
答案 0 :(得分:2)
bail out逻辑是在react-dom v16.8.0中实现的,其中react也引入了钩子,而您的演示使用钩子的alpha版本,这就是为什么即使在更新为时仍会触发重新渲染的原因相同状态
根据v16.8.0发行说明
- 避免对useState和useReducer Hooks使用相同的值进行渲染。 (@acdlite在#14569中)