Почему, когда просчитываю массив внутри useState, код работает, но когда выношу его создание в зависимости useEffect получаю ошибку?
Есть такой код постраничного скроллинга:
export default function Home() {
let currentOffset = 0
const handleScroll = () => {
let yPositions = []
yPositions = Array.from(document.getElementsByClassName('section__scroll')).map((sectionItem, index) => {
let yPosition = sectionItem.getBoundingClientRect().top + document.documentElement.scrollTop
yPositions.push(yPosition)
return yPosition
})
currentOffset = window.scrollY
let isScrollDown = true ? currentOffset > scroll.offset : false
setScroll(scroll.currentSectionIndex, currentOffset, scroll.scrolled)
if (currentOffset > 0) toTopBtnRef.current.classList.add("totopbtn--active")
else toTopBtnRef.current.classList.remove("totopbtn--active")
if (isScrollDown) {
if (scroll.scrolled >= 50) setScroll(scroll.scrolled = 49)
setScroll(scroll.scrolled = scroll.scrolled + 1)
console.log(scroll.scrolled)
if (scroll.scrolled >= 50 && scroll.currentSectionIndex < yPositions.length - 1) {
window.scrollTo({
top: yPositions[scroll.currentSectionIndex + 1],
behavior: 'smooth'
})
setScroll(scroll.currentSectionIndex = scroll.currentSectionIndex + 1, scroll.offset = currentOffset, scroll.scrolled = 0)
}
}
else if (!isScrollDown) {
if (scroll.scrolled < 0) setScroll(scroll.scrolled = 1)
setScroll(scroll.scrolled = scroll.scrolled - 1)
console.log(scroll.scrolled)
if (scroll.scrolled <= 1 && scroll.currentSectionIndex > 0) {
window.scrollTo({
top: yPositions[scroll.currentSectionIndex - 1] + scroll.scrolled,
behavior: 'smooth'
})
setScroll(scroll.currentSectionIndex = (scroll.currentSectionIndex - 1), scroll.offset = currentOffset, scroll.scrolled = 49)
}
}
}
let [scroll, setScroll] = useState({ currentSectionIndex: 0, offset: 0, scrolled: 0 });
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
}
});
return (
<section className = 'section__scroll'>content of the section</section>
<section className = 'section__scroll'>content of the section 2</section>
<section className = 'section__scroll'>content of the section 3</section>
<section className = 'section__scroll'>content of the section 4</section>
)
Сейчас итересует массив yPositions. Если его заполнять в handleScroll, то код ошибок не выдает. Но если его вынести в компонент Home и заполнить там, а в hanleScroll передать, как зависимость:
let currentOffset = 0
let yPositions = []
yPositions = Array.from(document.getElementsByClassName('section__scroll')).map((sectionItem, index) => {
let yPosition = sectionItem.getBoundingClientRect().top + document.documentElement.scrollTop
yPositions.push(yPosition)
return yPosition
})
const handleScroll = () => {
currentOffset = window.scrollY
let isScrollDown = true ? currentOffset > scroll.offset : false
setScroll(scroll.currentSectionIndex, currentOffset, scroll.scrolled)
if (currentOffset > 0) toTopBtnRef.current.classList.add("totopbtn--active")
else toTopBtnRef.current.classList.remove("totopbtn--active")
if (isScrollDown) {
if (scroll.scrolled >= 50) setScroll(scroll.scrolled = 49)
setScroll(scroll.scrolled = scroll.scrolled + 1)
console.log(scroll.scrolled)
if (scroll.scrolled >= 50 && scroll.currentSectionIndex < yPositions.length - 1) {
window.scrollTo({
top: yPositions[scroll.currentSectionIndex + 1],
behavior: 'smooth'
})
setScroll(scroll.currentSectionIndex = scroll.currentSectionIndex + 1, scroll.offset = currentOffset, scroll.scrolled = 0)
}
}
else if (!isScrollDown) {
if (scroll.scrolled < 0) setScroll(scroll.scrolled = 1)
setScroll(scroll.scrolled = scroll.scrolled - 1)
console.log(scroll.scrolled)
if (scroll.scrolled <= 1 && scroll.currentSectionIndex > 0) {
window.scrollTo({
top: yPositions[scroll.currentSectionIndex - 1] + scroll.scrolled,
behavior: 'smooth'
})
setScroll(scroll.currentSectionIndex = (scroll.currentSectionIndex - 1), scroll.offset = currentOffset, scroll.scrolled = 49)
}
}
}
let [sectionIndex, setSectionIndex] = useState(0);
let [scroll, setScroll] = useState({ currentSectionIndex: 0, offset: 0, scrolled: 0 });
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
}
}, [yPositions, currentOffset]);
return (
<section className = 'section__scroll'>content of the section</section>
<section className = 'section__scroll'>content of the section 2</section>
<section className = 'section__scroll'>content of the section 3</section>
<section className = 'section__scroll'>content of the section 4</section>
)
То при скролле получаю ошибку в консоли:
Home.js:76 Uncaught TypeError: Cannot read properties of undefined (reading 'offset') at handleScroll (Home.js:76:1)
И ошибки в на странице:
Cannot read properties of undefined (reading: 'offset') и
cannot create proparty 'scrolled' on number '2'