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

如何修复React分页功能中useEffect的无限循环问题

分页功能无限循环问题分析与修复

问题原因

  1. 无限循环触发逻辑:你把products加入了useEffect的依赖数组,同时在useEffect内部调用setProducts修改该状态。每次setProducts执行后,products状态更新,会再次触发useEffect运行,进而再次执行setProducts,形成无限循环。
  2. 原始数据丢失问题:你用切片后的分页数据覆盖了原始的products状态,导致切换页码时,原始产品数据已丢失,无法正确切出其他页的内容。

修复方案

核心思路是拆分状态职责,把原始产品数据和当前分页展示的数据分开处理:

  • 原始静态数据直接使用导入的data.products,无需存入状态(因为它不会变化)。
  • 新增displayProducts状态专门存储当前页要展示的切片数据。
  • 调整useEffect的依赖,只监听currentPage的变化,避免触发不必要的重执行。

修复后完整代码

import React, { useState, useEffect } from "react";
import data from './products.json'
import Product from "./components/Product/Product";

const PRODUCTS_PER_PAGE = 12

export const Shop = () => {
    const [currentPage, setCurrentPage] = useState(1)
    const [displayProducts, setDisplayProducts] = useState([])

    // 用原始数据计算总页数,避免依赖变化的状态
    const totalPages = Math.ceil(data.products.length / PRODUCTS_PER_PAGE)

    useEffect(() => {
        const firstIndex = (currentPage - 1) * PRODUCTS_PER_PAGE
        const lastIndex = firstIndex + PRODUCTS_PER_PAGE
        // 从原始数据中切片,保留完整数据源
        const slicedProducts = data.products.slice(firstIndex, lastIndex)
        setDisplayProducts(slicedProducts)
    }, [currentPage]) // 仅依赖currentPage,彻底避免循环

    return (
        <div className="products">
            {displayProducts.map((product) => (
                <Product key={product.id} product={product} /> // 必加key属性,符合React最佳实践
            ))}
            {/* 可选:添加分页控制按钮 */}
            <button 
                onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
                disabled={currentPage === 1}
            >
                上一页
            </button>
            <span>第 {currentPage} 页 / 共 {totalPages} 页</span>
            <button 
                onClick={() => setCurrentPage(prev => Math.min(prev + 1, totalPages))}
                disabled={currentPage === totalPages}
            >
                下一页
            </button>
        </div>
    )
}

补充说明

  • 你之前考虑移除products依赖的方向是对的,但单纯移除依赖无法解决原始数据丢失的问题,必须拆分状态才能实现正常分页。
  • 列表渲染时添加key属性是React的强制要求,能避免组件重渲染异常和控制台警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:55:20