我的目标是根据用户的滚动位置应用不同的 className。好吧,如果用户的滚动位置> 0,我需要更改导航栏的背景颜色。我想出了一个适用于所有情况的工作解决方案,除非用户加载页面并且初始滚动位置不是 0(滚动然后重新加载页面)。
我所做的是创建了一个自定义钩子(Hook),如下所示:
import { useState, useEffect } from 'react';
export default () => {
const [scrollPosition, setScrollPosition] = useState(
typeof window !== 'undefined' ? window.scrollY : 0,
);
useEffect(() => {
const setScollPositionCallback = () => setScrollPosition(window.scrollY);
if (typeof window !== 'undefined') {
window.addEventListener('scroll', setScollPositionCallback);
}
return () => {
if (typeof window !== 'undefined') {
window.removeEventListener('scroll', setScollPositionCallback);
}
};
}, []);
return scrollPosition;
};
然后我在我的导航栏组件中使用这个钩子(Hook):
...
const scrollPosition = useScrollPosition();
...
<Navbar
color={scrollPosition < 1 ? 'transparent' : 'white'}
...
/>
正如我所描述的,如果用户在 0 scrollY 处加载页面,一切都会很好。如果不是,我会收到警告
Warning: Prop className did not match
,这是预期的,因为 scrollY 在服务器端始终为 0,然后滚动不起作用,因为 Navbar 保持 ssr 类。处理它的正确方法是什么?
最佳答案
我找到了解决方案。它发生的原因是,由于钩子(Hook)中的这一行:
const [scrollPosition, setScrollPosition] = useState(
typeof window !== 'undefined' ? window.scrollY : 0,
);
在ssr上滚动位置一直等于0,但是在客户端加载时,它被设置为实际
scrollY
一开始。所以我所做的是我设置了初始
scrollPosition
通过将下面的行修改为:在客户端和服务器端都为 0:const [scrollPosition, setScrollPosition] = useState(0);
并且添加了一个仅在客户端有效的效果,它设置
scrollPosition
:useEffect(() => {
if (typeof window !== 'undefined' && window.scrollY !== 0) {
setScrollPosition(window.scrollY);
}
}, []);
关于reactjs - React SSR,处理页面滚动位置的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57230099/