React调用localhost:3001的Express API返回null的问题求助
问题描述
在React中使用useEffect和useState结合fetch获取JSON数组并渲染页面时,遇到以下问题:
- 用
json-server实现的localhost:3333/list接口可正常工作; - 切换到自研的Express API(
localhost:3001/peeps,同样包含id和name字段,未修改渲染代码)时,Fetch报错,data值为null; - API终端能输出JSON日志,说明请求已到达,但React无法获取数据。
已确认信息:
- 已给API添加
Access-Control-Allow-Origin: *; json-server接口有响应延迟,自研API无延迟。
已简化项目测试两天,仍未解决问题。
提供的代码
Express API控制器代码(Postman测试通过)
// Retrieve all Peeps from the database. exports.findAll = (req, res) => { Peep.getAll((err, data) => { if (err) res.status(500).send({ message: err.message || "Some error occurred while retrieving peeps." }); else { res.header("Access-Control-Allow-Origin", "*"); res.send(data); } }); };
React的App.js代码
import React, { useEffect, useState } from 'react'; import './App.css'; import { getList } from './services/list'; function App() { const [list, setList] = useState([]); useEffect(() => { let mounted = true; getList() .then(items => { if(mounted) { setList(items) } }) return () => mounted = false; }, []) alert(list); return( <div className="wrapper"> <h1>My List</h1> <ul> {list.map(item => <li key={item.item}>{item.item}</li>)} </ul> </div> ) } export default App;
排查与解决方案
1. 检查getList函数的响应处理
问题大概率出在getList的实现上,fetch需要显式调用.json()解析响应,同时要处理错误状态:
export const getList = () => { return fetch('http://localhost:3001/peeps') .then(res => { // 先验证响应状态 if (!res.ok) throw new Error(`HTTP错误: ${res.status}`); return res.json(); // 必须调用此方法解析JSON数据 }) .catch(err => { console.error('Fetch请求失败:', err); throw err; // 抛出错误以便组件捕获处理 }); };
2. 修正渲染代码的字段匹配
你的渲染代码使用item.item,但API返回的字段是id和name,字段不匹配会导致渲染失败甚至影响状态更新,需修改为:
{list.map(item => <li key={item.id}>{item.name}</li>)}
3. 全局设置CORS头
将CORS设置移到Express全局中间件,确保所有请求(包括错误响应)都带上跨域头:
const express = require('express'); const app = express(); // 全局CORS配置 app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); // 挂载路由 const peepsRouter = require('./routes/peeps'); app.use('/peeps', peepsRouter);
4. 替换调试方式并捕获错误
去掉alert(list)(会显示[object Object]且干扰调试),改用console.log查看数据,并添加错误捕获:
useEffect(() => { let mounted = true; getList() .then(items => { if(mounted) { console.log('获取到的数据:', items); setList(items); } }) .catch(err => { console.error('获取列表失败:', err); }); return () => mounted = false; }, []);
5. 确认API返回的数据结构
确保Express API返回的是数组格式的JSON,而非嵌套对象(比如{data: [...]}),如果是嵌套结构,getList里需要调整为return res.json().then(data => data.data)。
内容的提问来源于stack exchange,提问作者David L. Whitehurst
相关产品推荐
相关产品推荐

