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

如何配置React参数,通过Express动态调用API实现加载更多?

解决Express + React动态加载分页数据的问题

我帮你排查了代码里的几个关键问题,调整后就能实现点击「Load More」加载下一页数据的功能了:

问题分析

  • React的useEffect依赖缺失:你的useEffect依赖项是空数组[],这意味着它只会在组件挂载时执行一次,后续page状态改变时不会重新触发API请求,所以点击按钮后不会加载新数据。
  • React中错误使用node-fetch:node-fetch是给Node.js环境用的,浏览器环境直接用原生fetch即可,不需要额外引入这个包。
  • 状态更新的闭包陷阱:直接用[...products, ...contents.products]更新products状态时,可能会因为闭包问题获取到旧的products值,应该用函数式更新来避免这个问题。
  • 端口与参数小问题:React请求的端口和Express监听的端口不一致,同时参数命名可以更统一,减少歧义。

修正后的代码

Express 代码

const express = require('express');
const fetch = require('node-fetch');
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'build')));

app.get('/products', (req, res) => {
  // 统一参数名为page,设置默认值避免无参数时出错
  const page = req.query.page || 1;
  const url = `https://frontend-intern-challenge-api.iurykrieger.now.sh/products?page=${page}`;
  
  fetch(url)
    .then(response => response.json())
    .then(contents => {
      res.send({ 
        products: contents.products, 
        nextPage: contents.nextPage 
      });
    })
    .catch(err => {
      // 增加错误处理,方便排查问题
      console.error('获取数据失败:', err);
      res.status(500).send({ error: 'Failed to fetch products' });
    });
});

app.listen(process.env.PORT || 8080, () => {
  console.log('服务器已启动,监听端口8080');
});

React 组件代码

import React, { useEffect, useState } from 'react';

const Products = () => {
  const [products, setProducts] = useState([]);
  const [page, setPage] = useState(1);
  // 增加加载状态优化用户体验
  const [isLoading, setIsLoading] = useState(false);

  const loadProduct = () => {
    // 用函数式更新page,确保拿到最新状态值
    setPage(prevPage => prevPage + 1);
  };

  useEffect(() => {
    const fetchProducts = async () => {
      setIsLoading(true);
      try {
        // 修正请求端口,和Express监听的8080保持一致
        const response = await fetch(`http://localhost:8080/products?page=${page}`);
        const contents = await response.json();
        // 函数式更新products,避免闭包导致的旧状态问题
        setProducts(prevProducts => [...prevProducts, ...contents.products]);
      } catch (err) {
        console.error('加载产品失败:', err);
      } finally {
        setIsLoading(false);
      }
    };

    fetchProducts();
  }, [page]); // 依赖page状态,page变化时自动触发请求

  return (
    <div>
      {products.map((product, index) => (
        // 给列表项加唯一key,避免React警告(实际项目建议用product的唯一id)
        <p key={index}>{product.name}</p>
      ))}
      <button 
        type="button" 
        onClick={loadProduct}
        disabled={isLoading}
      >
        {isLoading ? '加载中...' : 'Load More'}
      </button>
    </div>
  );
};

export default Products;

额外说明

我给代码加了错误处理和加载状态提示,既方便开发者排查问题,也能提升用户体验;另外注意确保React请求的端口和Express监听的端口一致,这是很容易忽略的细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:15:30