我正在try 构建一个无限滚动加载器组件,但不知何故,我的‘Items’数组重置为[](清空),而不是像我预期的那样附加新的结果.

有几件事需要注意:

  1. 当观察者进入视线时,我在网络选项卡中看到API调用.
  2. 接口返回的数据 fresh 唯一(无缓存问题)

以下是相关的行文: setItems([...items, ...data.data]);//Items正在重置为[],data.data总是一组新的新值

"use client";
import { useState, useEffect, useRef } from "react";

export function HBSInfiniteScrollList({ request = {} }) {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const observerTarget = useRef(null);

  const fetchData = async () => {
    setLoading(true);
    try {
      const res = await fetch(request.url, request.options);
      if (res.ok) {
        const data = await res.json();        
        setItems([...items, ...data.data]);
      } else {
      }
    } catch (err) {
      console.log(err);
      setError(err);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          console.log("isIntersecting, fetching new data...");
          fetchData();
        }
      },
      { threshold: 1 }
    );

    if (observerTarget.current) {
      observer.observe(observerTarget.current);
    }

    return () => {
      if (observerTarget.current) {
        observer.unobserve(observerTarget.current);
      }
    };
  }, [observerTarget]);

  return (
    <div>
      <ul className="list-group">
        {items.map((item) => (
          <li key={item.id} className="list-group-item">
            {item.name}
          </li>
        ))}
      </ul>
      {loading && <p>Loading...</p>}
      {error && <p>Error: {error.message}</p>}
      length: {items.length}
      <div ref={observerTarget}></div>
    </div>
  );
}

有谁觉得有什么不对劲吗?这种类型的代码我已经写了一百万次了.也许我只是累了.

推荐答案

由于useState的异步性质,如果fetchData被快速连续地调用多次,那么在每次更新时,项可能没有最新的值.这是因为状态更新可能尚未应用,导致重复先前的更新.

为了确保在更新时始终具有最新状态,您应该对setItems使用函数式更新.这可以保证您使用的是该州的最新值.

您必须修改将项的状态更新为以下内容的代码行:

setItems(prevItems => [...prevItems, ...data.data]);

prevItems是由React的setState函数提供的参数,该函数在应用更新时自动保存最新状态.

这样可以确保您在更新时始终使用最新的状态.

Javascript相关问答推荐

我试图实现用户验证的reduxstore 和操作中出了什么问题?

我应该在redux reducer中调用其他reducer函数吗?

我可以使用CSS有效地实现最大宽度=100%和最大高度=100%,而无需父母有明确的/固定的宽度和高度,替代方法吗?

当点击注册页面上的注册按钮时,邮箱重复

屏幕右侧屏障上的产卵点""

无法访问Vue 3深度监视器中对象数组的特定对象值'

我在我的Java代码中遇到了问题,代码的一部分看不到先前定义的对象

虚拟滚动实现使向下滚动可滚动到末尾

单个HTML中的多个HTML文件

Next.js中的服务器端组件列表筛选

未捕获语法错误:Hello World中的令牌无效或意外

不协调嵌入图片

AG-GRIDreact 显示布尔值而不是复选框

在HTML5画布上下文中使用putImageData时,重载解析失败

为什么我的Navbar.css没有显示在本地主机页面上?

JavaScript:多个图像错误处理程序

输入数据覆盖JSON文件

扩散运算符未按预期工作,引发语法错误

我想为我的Reaction项目在画布上加载图像/视频,图像正在工作,但视频没有

:host::ng-Deep不将样式应用于material 复选框