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

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

问题原因

  1. Node端Promise错误:核心是跨域问题,浏览器同源策略阻止React(默认3000端口)访问Node服务(同端口冲突或跨端口/域名),且服务端未处理OPTIONS预检请求,导致Promise报错。另外,Node与React同用3000端口会导致服务启动失败,间接引发请求错误。
  2. 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
    

验证步骤

  1. 启动Node服务:执行node server.js(替换为你的服务文件名)
  2. 启动React项目:执行npm start
  3. 访问React项目(默认http://localhost:3000),即可正常加载笑话列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:46:06