Реагируйте крюками. Почему не устанавливается состояние изменения функции? - PullRequest
1 голос
/ 06 марта 2019
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) всегда срабатывает, но, кажется, никогда не меняет состояние.Зачем?По сути, isHidden никогда не устанавливается в false, кроме как после инициализации useState.

1 Ответ

3 голосов
/ 06 марта 2019

В основном получается, что ваш useEffect работает только два раза при монтировании и при размонтировании (, и это явно преднамеренно ), однако нежелательным побочным эффектом этого является то, что значение isHidden, котороевы проверяете, что метод onScroll закрывается по его начальному значению (которое false) - навсегда ( до тех пор, пока не отключится ).

Вы можете использовать функциональныйформа сеттера, где он получает действительное значение состояния и помещает в него всю логику ветвления.Что-то вроде:

  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 {
        // ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...