React Hooks,如何实现useHideOnScroll钩子? [英] React Hooks, how to implement useHideOnScroll hook?

查看:353
本文介绍了React Hooks,如何实现useHideOnScroll钩子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

const shouldHide = useHideOnScroll();
return shouldHide ? null : <div>something</div>

useHideOnScroll行为不应在每次滚动时都返回更新的值,而应仅在发生更改时返回更新的值.

The useHideOnScroll behaviour should return updated value not on every scroll but only when there is a change.

伪逻辑如下:

if (scrolledDown && !isHidden) {
        setIsHidden(true);
      } else if (scrolledUp && isHidden) {
        setIsHidden(false);
      }

换句话说,如果向下滚动而不是隐藏,则隐藏.如果向上滚动并隐藏,则取消隐藏.但是,如果向下滚动并隐藏,则不执行任何操作;或者向上滚动但不隐藏,则不执行任何操作.

In words, if scroll down and not hidden, then hide. If scroll up and hidden, then unhide. But if scroll down and hidden, do nothing or scroll up and not hidden, do nothing.

如何用钩子实现呢?

推荐答案

此处:

const useHideOnScroll = () => {
  const prevScrollY = React.useRef<number>();
  const [isHidden, setIsHidden] = React.useState(false);

  React.useEffect(() => {
    const onScroll = () => {
      setIsHidden(isHidden => {
        const scrolledDown = window.scrollY > prevScrollY.current!;
        if (scrolledDown && !isHidden) {
          return true;
        } else if (!scrolledDown && isHidden) {
          return false;
        } else {
          prevScrollY.current = window.scrollY;
          return isHidden;
        }
      });
    };

    console.log("adding listener");
    window.addEventListener("scroll", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
    };
  }, []);

  return isHidden;
};

const Navbar = () => {
  const isHidden = useHideOnScroll();
  console.info("rerender");
  return isHidden ? null : <div className="navbar">navbar</div>;
};

export default Navbar;

您可能会担心setIsHidden会在每个onScroll上重新渲染,总是返回一些新的状态值,但是useState中的setter很聪明,只有在值实际更改时才进行更新.

You might have concern about setIsHidden causing rerender on every onScroll, by always returning some new state value, but a setter from useState is smart enough to update only if the value has actually changed.

另外,您的.navbar(我已经向其中添加了一个类)不应在布局出现时更改布局,否则您的代码段将陷入无限循环中.这也是适合的样式:

Also your .navbar (I've added a class to it) shouldn't change the layout when it appears or your snippet will get locked in an infinite loop. Here're appropriate styles for it as well:

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 30px;
  background: rgba(255, 255, 255, 0.8);
}

完整的CodeSandbox: https://codesandbox.io/s/13kr4xqrwq

Full CodeSandbox: https://codesandbox.io/s/13kr4xqrwq

这篇关于React Hooks,如何实现useHideOnScroll钩子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆