You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用React实现书架无限滚动加载 首次渲染9本滚动到底部自动加载更多

问题原因分析

你编写的CallBooks组件无法正常运行的核心问题如下:

  • 循环条件写反:初始Load=0,Load>props.number永远不成立,函数无返回值,无内容渲染
  • 循环内提前return:即使条件成立,第一次循环就会return单个Book组件,后续的SetLoad逻辑永远不会执行,无法生成多个组件
  • React不支持通过循环中多次return的方式渲染列表,需要返回包含多个子元素的集合
实现方案

1. 修正CallBooks组件

接收count参数,渲染指定数量的Book组件,代码如下:

import React from "react";
import Book from './Book';

const CallBooks = (props) => {
  return (
    <>
      {Array.from({ length: props.count }, (_, index) => (
        <Book key={index} number={index} />
      ))}
    </>
  );
};

export default CallBooks;

提示:如果Book.json里有书籍的唯一id,建议用id作为key替换index,渲染性能更好。

2. 实现无限滚动逻辑

在BookFeed组件中实现滚动监听、自动加载逻辑,首次渲染9本,滚动到底部自动加载更多,代码如下:

import React, { useState, useEffect, useCallback } from "react";
import CallBooks from './CallBooks';
import './Book.css';
import Books from "./Book.json";

const BookFeed = () => {
  // 初始渲染9本
  const [renderCount, setRenderCount] = useState(9);
  // 加载状态防止重复触发加载
  const [isLoading, setIsLoading] = useState(false);
  // 书籍总数量
  const totalBooks = Books.length;

  const handleScroll = useCallback(() => {
    // 加载中或者已经加载完全部书籍直接终止逻辑
    if (isLoading || renderCount >= totalBooks) return;
    // 计算滚动位置,提前50px触发加载体验更顺滑
    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    const clientHeight = document.documentElement.clientHeight;
    const scrollHeight = document.documentElement.scrollHeight;
    if (scrollTop + clientHeight >= scrollHeight - 50) {
      setIsLoading(true);
      // 模拟接口请求延迟,本地数据可以直接删除setTimeout
      setTimeout(() => {
        // 每次加载3本,可自行调整数值
        setRenderCount(prev => Math.min(prev + 3, totalBooks));
        setIsLoading(false);
      }, 300);
    }
  }, [isLoading, renderCount, totalBooks]);

  // 绑定/解绑滚动监听事件
  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, [handleScroll]);

  return (
    <div className='books'>
      <CallBooks count={renderCount} />
      {isLoading && <div className="loading">加载中...</div>}
      {renderCount >= totalBooks && <div className="no-more">没有更多书籍了</div>}
    </div>
  );
};

export default BookFeed;

内容的提问来源于stack exchange,提问作者kizaru13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:06:04