如何配置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
相关产品推荐
相关产品推荐

