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

时间:2019-03-06 06:59:18

标签: reactjs state react-hooks

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

Full example

console.log(`is hidden ${isHidden}`);始终打印为false,并且setIsHidden(true)始终被触发,但似乎从未改变状态。为什么?基本上,除非在useState初始化之后,否则isHidden绝不会设置为false。

1 个答案:

答案 0 :(得分:3)

基本上发生的是,您的useEffect在挂载和卸载时仅运行两次(这显然是有意的),但是此操作的有害副作用是{在isHidden方法中检查的{1}}会因其初始值(onScroll)而被关闭-直到永远(直到卸载)。

您可以使用设置器的功能形式,在该设置器中接收状态的实际值并将所有分支逻辑放入其中。像这样:

false