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

React+Node结合Redux状态实现加载更多按钮的问题求解

问题分析与解决方案

问题1:旧数据无法保留、修改合并逻辑后报类型错误

原因

  1. 原Reducer逻辑每次拉取新数据后直接覆盖products和originalItems字段,旧数据自然被清除
  2. 合并数组时报错是因为Reducer初始状态中没有给products、originalItems设置默认空数组,首次加载时state.products为undefined,展开undefined会直接抛出类型错误
  3. 额外注意:需确保接口返回的payload.data是标准商品数组,若后端接口返回格式嵌套层级错误也会导致合并失败

修复方案

  1. 先修正Reducer的初始状态,给列表字段设置默认空数组
  2. 合并数组时添加兜底逻辑,避免偶发的undefined报错
  3. 后端接口需要返回商品总数量,用来后续判断是否还有更多数据可加载

修正后Reducer代码:

// 初始状态示例
const initialState = {
  products: [],
  originalItems: [],
  total: 0, // 新增字段存商品总数量
  // 其余原有状态保持不变
}

// PRODUCT_FETCH分支逻辑
case "PRODUCT_FETCH":
  return {
    ...state,
    products: [...(state.products || []), ...payload.data],
    originalItems: [...(state.originalItems || []), ...payload.data],
    total: payload.total // 存储后端返回的总数量
  };

修正后后端返回逻辑:

const { skip, limit } = req.body;
let products = await Product.find()
  .populate("category")
  .skip(skip)
  .limit(limit);
let productsLength = await Product.find().countDocuments();

// 调整返回格式,同时返回商品列表和总数量
res.json({
  data: products,
  total: productsLength
})

问题2:skip参数不递增、重复拉取最后一页数据

原因

你当前使用的Skip变量没有存入组件状态,在handleLoadMore中计算完新的skip值后没有更新存储的Skip变量,下次触发加载时还是用初始值计算,导致每次请求的分页参数完全相同。

修复方案

将Skip存入组件的useState状态,每次加载新数据后更新状态值,同时新增是否还有更多数据的判断,避免无效请求。

修正后ProductList.jsx代码:

import { useState, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'

const ProductList = () => {
  const dispatch = useDispatch()
  // 从Redux取商品列表、总数量
  const { products, total } = useSelector(state => state.product)
  // 把skip存入组件状态,初始值为0
  const [Skip, setSkip] = useState(0)
  // 分页大小可根据需求调整
  const Limit = 10
  const [filterProduct, setFilterProduct] = useState([])
  // 控制是否还有更多数据可加载
  const [hasMore, setHasMore] = useState(true)

  useEffect(() => {
    setFilterProduct(products);
    // 每次商品列表更新后判断是否还有剩余数据未加载
    setHasMore(products.length < total)
  }, [products, total]);

  useEffect(() => {
    const data = {
      skip: Skip,
      limit: Limit,
    };
    dispatch(fetchNewProducts(data));
  }, []);

  const handleLoadMore = () => {
    // 没有更多数据时直接终止请求
    if(!hasMore) return
    const newSkip = Skip + Limit;
    // 更新skip状态,保证下次加载用新的参数计算
    setSkip(newSkip)
    const data = {
      skip: newSkip,
      limit: Limit,
    };
    dispatch(fetchNewProducts(data));
  };

  // 渲染逻辑可自行调整,加载更多按钮建议加 disabled={!hasMore} 状态
  return (
    {/* 商品列表渲染 */}
    <button onClick={handleLoadMore} disabled={!hasMore}>
      {hasMore ? '加载更多' : '没有更多商品了'}
    </button>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:54:04