Я хочу создать бесконечную прокрутку с нуля. Вот код:
import React,{useEffect, useRef, useState} from 'react';
const Container:React.FC<{}> = () => {
const containerRef = useRef<HTMLDivElement | null>(null)
const [ scrollNumber, setScrollNumber ] = useState<number>(1);
const [posts, setPosts] = useState<any[]>([]);
useEffect(() => {
async function main(){
const req = await fetch('https://jsonplaceholder.typicode.com/posts');
const result = await req.json();
const pst = result.splice(0,10*scrollNumber);
setPosts(pst)
function scrollHandler(){
if (containerRef.current?.getBoundingClientRect().bottom === window.innerHeight){
console.info("Salam", scrollNumber);
setScrollNumber(scrollNumber + 1);
}
}
window.addEventListener("scroll", scrollHandler);
return () => window.removeEventListener("scroll", scrollHandler);
}
main()
},[])
useEffect(() => {
const loadData = async () => {
const req = await fetch('https://jsonplaceholder.typicode.com/posts');
const result = await req.json();
const pst = result.splice(0,10*scrollNumber);
setPosts(pst)
}
loadData()
},[scrollNumber])
return (
<div ref = {containerRef}>
{posts.map(post => (
<div key = {post.id}>
<br/>
<h1>{post.title}</h1>
(<p>{post.body}</p>)
<code>{post.userId}</code>
<br/><br/>
<hr/>
</div>
))}
</div>
)
}
export default Container
Но есть проблема. Когда буду тестить. он всегда обновляется до 2 и больше ничего. Я искал это. Я обнаружил, что window.addEventListener помнит только initialState, поэтому состояние всегда обновляется до 2. Но я не смог найти никакого решения для кода.
внутри первого useEffect
массив зависимостей пуст, что означает, что если вы используете внутри него какую-либо переменную состояния, ее значение не изменится внутри эффекта
Как я вижу, вы используете scrollNumber
для установки следующего состояния setScrollNumber(scrollNumber + 1);
, а значение scrollNumber
не изменится внутри эффекта, потому что массив зависимостей пуст
Таким образом, вы должны сообщить реакции, чтобы повторно инициализировать эффект, если у вас есть какие-либо изменения в scrollNumber
поэтому поставьте scrollNumber
, так как зависимость будет работать на вас
useEffect(() => {
...
function scrollHandler(){
if (containerRef.current?.getBoundingClientRect().bottom === window.innerHeight) {
console.info("Salam", scrollNumber);
setScrollNumber(scrollNumber + 1);
}
}
window.addEventListener("scroll", scrollHandler);
return () => window.removeEventListener("scroll", scrollHandler);
.....
}, [scrollNumber]) //add a dependency
Это должно произойти, потому что вы поместили scrollNumber
в качестве зависимости для второго useEffect, поэтому, когда scrollNumber
получите эффект изменения, вызовет и произойдет выборка, если вам это не нужно, удалите его из массива зависимостей второго useEffect.
нп, рад помочь вам
когда я добавляю scrollNumber в качестве зависимости, он начинает повторять выборку несколько раз