React SSR,正确处理页面滚动位置的方法

时间:2019-07-27 07:32:19

标签: reactjs next.js ssr

我的目标是根据用户的滚动位置应用不同的className。好吧,如果用户的滚动位置> 0,则需要更改导航栏的背景颜色。我想出了一种在所有情况下都可以使用的解决方案,但如果用户加载页面且初始滚动位置不为0(滚动,然后重新加载页面)。

我所做的是创建了一个看起来像这样的自定义钩子:

this.client.post<number>(endpoint, dto.userDto).subscribe(x =>
  result = x)

然后在Navbar组件中使用此钩子:

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;
};

正如我所描述的,如果用户在0 scrollY处加载页面,一切都将正常工作。否则,我得到警告... const scrollPosition = useScrollPosition(); ... <Navbar color={scrollPosition < 1 ? 'transparent' : 'white'} ... /> ,这是预料之中的,因为在服务器端,scrollY始终为0,然后滚动不起作用,因为Navbar保留ssr类。

正确的处理方式是什么?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。之所以发生这种情况,是因为钩子中的这一行:

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);
  }
}, []);