c13*_*137 5 javascript reactjs react-hooks
我只是在玩 ReactJS 并试图通过 useState 钩子找出一些奇怪的行为。
如果状态设置为与之前相同的原始值(布尔值),则不应重新渲染组件
const useScroll = ({positionToCross = 10}) => {
const window = useWindow();
const [isPositionCrossed, setIsPositionCrossed] = useState(window.scrollY > positionToCross);
useEffect(() => {
const onScroll = function (e) {
window.requestAnimationFrame(function () {
const lastKnownScrollPosition = window.scrollY;
setIsPositionCrossed(lastKnownScrollPosition > positionToCross);
});
}
window.addEventListener('scroll', onScroll);
return () => {
window.removeEventListener("scroll", onScroll)
}
}, []);
console.log(`useScroll - render window.scrollY = ${window.scrollY.toFixed(0)} isPositionCrossed = `, isPositionCrossed)
return {isPositionCrossed}
}
Run Code Online (Sandbox Code Playgroud)
这是控制台输出 - 您可以看到组件和钩子都以“true”渲染两次(滚动超过 100px 后)
"useScroll - render window.scrollY = 101 isPositionCrossed = ", true
"useScroll - render window.scrollY = 103 isPositionCrossed = ", true
Run Code Online (Sandbox Code Playgroud)
如果您尝试在单击处理程序 setState 上使用简单的代码,并且单击两次并且在每个具有相同值的更新状态下,组件会再次重新渲染。\n正如反应文档所述:
\n\n\n如果将 State Hook 更新为与当前状态相同的值,React 将退出而不渲染子项或触发效果。(React 使用 Object.is 比较算法。)
\n请注意,React 可能仍需要在退出之前再次渲染该特定组件。这不应该成为一个问题,因为 React 不会不必要地将 \xe2\x80\x9cdeeper\xe2\x80\x9d 放入树中。如果您\xe2\x80\x99在渲染时进行昂贵的计算,您可以使用useMemo对其进行优化。
\n
我希望这篇文章和github 讨论中的答案 可以帮助您理解为什么会发生这种情况
\n\n| 归档时间: |
|
| 查看次数: |
732 次 |
| 最近记录: |