繁体   English   中英

反应钩。 为什么不设置功能改变状态?

[英]React hooks. Why doesn't set function change state?

const Navbar = () => {
  const prevScrollY = React.useRef<number>();

  const [isHidden, setIsHidden] = React.useState(false);

  React.useEffect(() => {
    const onScroll = () => {
      const scrolledDown = window.scrollY > prevScrollY.current!;
      console.log(`is hidden ${isHidden}`);
      if (scrolledDown && !isHidden) {
        setIsHidden(true);
        console.log(`set hidden true`);
      } else if (!scrolledDown && isHidden) {
        console.log(`set hidden false. THIS NEVER HAPPENS`);
        setIsHidden(false);
      }

      prevScrollY.current = window.scrollY;
    };

    console.log("adding listener");

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

  return isHidden ? null : <div>navbar</div>;
};

完整的例子

console.log(`is hidden ${isHidden}`); 总是打印false,并且setIsHidden(true)总是被触发但似乎永远不会改变状态。 为什么? 除了useState初始化之外,isHidden基本上不会设置为false。

基本上会发生的事情是你的useEffect在mount和unmount上只运行两次( 这显然是故意的 ),但是这样做的不良副作用是你在onScroll方法中检查的isHidden的值被isHidden了初始值(为false ) - 永远( 直到卸载 )。

您可以使用setter的函数形式,它接收状态的实际值并将所有分支逻辑放入其中。 就像是:

  setIsHidden(isHidden => { // <- this will be the proper one
     const scrolledDown = window.scrollY > prevScrollY.current!;
     console.log(`is hidden ${isHidden}`);
     if (scrolledDown && !isHidden) {
        console.log(`set hidden true`);
        return true;  
      } else if (!scrolledDown && isHidden) {
        console.log(`set hidden false. THIS NEVER HAPPENS`);
        return false;
      } else {
        // ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM