Node.js后端API正常,React前端Fetch获取数据返回空数组求助
问题:React前端无法获取Node.js后端数据,控制台输出空数组
我在Node.js后端编写了如下GET API,通过Postman测试可正常工作:
app.get("/todos", async(req, res)=>{ try { const allTodos = await pool.query("select * from todo;"); res.json(allTodos.rows); } catch (err) { console.error(err.message); } })
但在React前端的ListTodo.js组件中尝试获取数据并渲染时,console.log(jsonData)得到两个空数组,无法正常渲染数据,组件代码如下:
import React, { Fragment, useState, useEffect } from "react"; const ListTodo = () =>{ const [todos, setTodos] = useState([]); const getTodos = async() => { try { const response = await fetch("http://localhost:5000/todos") const jsonData = await response.json(); setTodos(jsonData) } catch (err) { console.error(err.message); } } useEffect = (()=> { getTodos(); }, []); console.log(todos); return ( <Fragment> <table class="table"> <thead> <tr> <th>Description</th> <th>Edit</th> <th>Delete</th> </tr> </thead> <tbody> {todos.map(todo => ( <tr> <td>{todo.description}</td> <td>Edit</td> <td>Delete</td> </tr> ))} </tbody> </table> </Fragment> ); } export default ListTodo;
解决方案
1. 修复useEffect的语法错误
这是核心问题——你把useEffect写成了赋值语句,导致getTodos函数根本不会执行。正确写法是调用useEffect函数:
useEffect(()=> { getTodos(); }, []);
2. 处理跨域问题(必做)
浏览器有同源策略,React默认运行在3000端口,后端在5000端口属于不同源,请求会被浏览器拦截。需要在Node.js后端配置CORS:
- 安装cors包:
npm install cors
- 在后端代码中引入并启用:
const cors = require('cors'); app.use(cors());
3. 完善fetch的错误处理
fetch只有在网络完全失败时才会进入catch,HTTP错误状态码(比如500、404)不会触发,需要手动判断响应状态:
const getTodos = async() => { try { const response = await fetch("http://localhost:5000/todos"); // 检查响应是否正常 if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } const jsonData = await response.json(); setTodos(jsonData); console.log(jsonData); // 这里就能看到正确返回的数据了 } catch (err) { console.error(err.message); } }
4. 关于两次空数组的说明
React组件初始渲染时,todos是初始的空数组,会先打印一次;如果之前的语法错误导致getTodos没执行,组件更新时todos还是空数组,就会打印两次空。修复后,第二次打印应该能看到后端返回的真实数据。
内容的提问来源于stack exchange,提问作者user19069531
相关产品推荐
相关产品推荐

