Почему не обновляется defaultValue при вызове setScroll?

Рейтинг: 0Ответов: 1Опубликовано: 18.04.2023

Пытаюсь реализовать посекционный скролл на сайте. Есть state, который назвал scroll:


    const [scroll, setScroll] = useState({ currentSectionIndex: 0 });
    useEffect(() => {
        window.addEventListener("scroll", handleScroll);

        return () => window.removeEventListener("scroll", handleScroll);

Обновить состояние пытаюсь в handleScroll:


    const handleScroll = () => {


        let currentScrollPosition = window.scrollY


        //window.scrollTo(0, yPositions[scroll])
        setScroll({ ...scroll, currentSectionIndex: scroll.currentSectionIndex + 1 })
        let windowScrolls = window.scrollY;
        console.log(scroll)
};

Но в currentSectionIndex при скролле выводится значение по умолчанию 0. Почему? setScroll же должен обновлять состояние в функциональном компоненте. Что делаю не так?

Ответы

▲ 1Принят

Доброго времени суток.

Когда меняете стейт с учетом содержимого, то стоит помнить, что он работает асинхронно. Поэтому у вас в значение scroll не всегда будет попадать нужное вам значение. В таких случаях стоит пользоваться callback функцией для установки стейта

Выглядит она следующим образом:

setScroll((state) => ({
  ...state,
  currentSectionIndex: state.currentSectionIndex + 1
}));

В таком случае в стейте будет верное значение.

Весь код будет таким

const [scroll, setScroll] = useState({
  currentSectionIndex: 0
});

useEffect(() => {
  window.addEventListener("scroll", handleScroll);

  return () => window.removeEventListener("scroll", handleScroll);
}, []);

useEffect(() => {
  console.log(scroll);
}, [scroll]);

const handleScroll = () => {
  setScroll((state) => ({
    ...state,
    currentSectionIndex: state.currentSectionIndex + 1
  }));
};

Если остались какие-то вопросы, то задавайте. Удачи!