代码沙箱
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可能仍然需要再次渲染该特定组件。这不应该是一个问题,因为反应不会不必要地“深入”树。如果您在渲染时进行昂贵的计算,您可以使用useMemo优化它们。
在我给出的示例中,我们可以看到useEffect钩子没有启动(如文档所述),但是我的Foo
组件正在渲染。
为什么会这样?
我想也许内联函数会导致渲染——但是如果我使用useCallback
将其更改为记忆化函数,同样的行为会发生:
const handleClick = useCallback(() => setValue(value), [value]);
console.log("rendering");
return (
<div>
{" "}
<Foo /> <button onClick={handleClick}>Click To Render</button>
</div>
保释逻辑是在react-dom的v16.8.0中实现的,在v16.8.0中,react-dom还引入了钩子,而你的演示使用了钩子的alpha版本,这就是为什么你仍然看到重新渲染被触发,即使你更新了相同的状态
根据v16.8.0版本说明