Window.addEventListener не обновляет состояние, как ожидалось

Я хочу создать бесконечную прокрутку с нуля. Вот код:

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. Но я не смог найти никакого решения для кода.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
743
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

внутри первого 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 в качестве зависимости, он начинает повторять выборку несколько раз

Ek4m 10.12.2020 08:14

Это должно произойти, потому что вы поместили scrollNumber в качестве зависимости для второго useEffect, поэтому, когда scrollNumber получите эффект изменения, вызовет и произойдет выборка, если вам это не нужно, удалите его из массива зависимостей второго useEffect.

Kalhan.Toress 10.12.2020 08:16

нп, рад помочь вам

Kalhan.Toress 10.12.2020 08:59

Другие вопросы по теме