Node.js发送响应出现Promise未捕获错误,React map函数报错
Node.js接口Promise错误与React遍历TypeError问题解决
问题现象
- Node.js编写的
/jokes接口返回数据时出现Uncaught (in promise)错误,尝试res.send和res.json均无法解决 - React项目调用该接口后,使用
map函数遍历jokes状态时触发TypeError: jokes.map is not a function错误
相关代码
Node.js服务端代码
import express from "express"; const app = express(); const port = process.env.PORT || 3000; app.get('/jokes', (req ,res) => { const jokes = [ { id: 1, title: 'Why don\'t scientists trust atoms?', content: 'Because they make up everything!' }, { id: 2, title: 'Did you hear about the mathematician who\'s afraid of negative numbers?', content: 'He\'ll stop at nothing to avoid them!' }, { id: 3, title: 'Why did the scarecrow win an award?', content: 'Because he was outstanding in his field!' }, { id: 4, title: 'Why don\'t skeletons fight each other?', content: 'They don\'t have the guts!' }, { id: 5, title: 'What do you call fake spaghetti?', content: 'An impasta!' } ]; res.send(jokes); }); app.listen(port, () => { console.log(`Server at http://localhost:${port}`); });
React前端代码
import { useEffect, useState } from "react" import React from "react" import axios from 'axios' import './App.css' function App() { const [jokes, setJokes] = useState([]) useEffect(() => { axios.get('http://localhost:3000/jokes') .then((response) =>{ setJokes(response.data) }) .catch((error) =>{ setJokes(error) }) }, []) return ( <> <h1>Fullstack</h1> <p>JOKES : {jokes.length}</p> { jokes.map((joke,index) =>{ <div key={joke.id} > <h3>{joke.title}</h3> <h3>{joke.title}</h3> </div> }) } </> ) } export default App
问题原因
- Node端Promise错误:核心是跨域问题,浏览器同源策略阻止React(默认3000端口)访问Node服务(同端口冲突或跨端口/域名),且服务端未处理OPTIONS预检请求,导致Promise报错。另外,Node与React同用3000端口会导致服务启动失败,间接引发请求错误。
- React端map错误:请求失败时,
setJokes(error)将jokes从数组改为Error对象,而对象没有map方法;同时map函数未返回元素,即使请求成功也无法渲染内容。
解决方案
1. 修复Node.js服务端
- 安装
cors中间件处理跨域:npm install cors - 修改服务端代码:
import express from "express"; import cors from "cors"; const app = express(); app.use(cors()); // 启用跨域支持 const port = process.env.PORT || 5000; // 修改端口避免与React冲突 app.get('/jokes', (req ,res) => { const jokes = [ { id: 1, title: '为什么科学家不信任原子?', content: '因为万物都是由它们组成的!' }, { id: 2, title: '你听说过害怕负数的数学家吗?', content: '他拼尽全力也要避开它们!' }, { id: 3, title: '为什么稻草人得了奖?', content: '因为他在自己的领域里太出色了!' }, { id: 4, title: '为什么骷髅不互相打架?', content: '因为他们没那个胆量!' }, { id: 5, title: '假意大利面叫什么?', content: 'Impasta(谐音骗子)!' } ]; res.json(jokes); // 用res.json规范返回JSON格式 }); app.listen(port, () => { console.log(`服务器运行在 http://localhost:${port}`); });
2. 修复React前端
- 修改前端代码:
import { useEffect, useState } from "react" import axios from 'axios' import './App.css' function App() { const [jokes, setJokes] = useState([]) const [error, setError] = useState(null) // 单独维护错误状态 useEffect(() => { axios.get('http://localhost:5000/jokes') // 对应Node服务的5000端口 .then((response) =>{ setJokes(response.data) setError(null) }) .catch((err) =>{ setError('获取笑话失败:' + err.message) setJokes([]) // 失败时重置为数组,保证map可调用 }) }, []) return ( <> <h1>全栈笑话</h1> {error && <p style={{color: 'red'}}>{error}</p>} <p>笑话数量:{jokes.length}</p> { jokes.map((joke) =>{ return ( // 必须返回渲染元素 <div key={joke.id} className="joke-card"> <h3>{joke.title}</h3> <p>{joke.content}</p> </div> ) }) } </> ) } export default App
验证步骤
- 启动Node服务:执行
node server.js(替换为你的服务文件名) - 启动React项目:执行
npm start - 访问React项目(默认http://localhost:3000),即可正常加载笑话列表
内容的提问来源于stack exchange,提问作者Pranay Chhibber
相关产品推荐
相关产品推荐

