【发布时间】:2021-12-31 18:03:45
【问题描述】:
我只是在玩 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}
}
这里是控制台输出 - 你可以看到组件和钩子都用“true”渲染了两次(滚动超过 100 像素后)
"useScroll - render window.scrollY = 101 isPositionCrossed = ", true
"useScroll - render window.scrollY = 103 isPositionCrossed = ", true
【问题讨论】:
-
你是在一个开启
StrictMode的开发环境中运行的,在16.8.0以上的React版本中运行吗?在这种情况下,许多函数被有意调用两次以帮助调试副作用,但在生产构建中它们只被调用一次,正如您所期望的那样。 -
我只是试图在我的应用程序中删除
StrictMode,它的行为相同。 React 版本是17.0.2 -
一般来说,“为什么 React 多次调用我的组件函数”是一个不必要的问题。 React 完全可以随意调用你的函数多次。这就是为什么函数应该是纯的(除了钩子)。
标签: javascript reactjs react-hooks