React替换json-server为PHP接口后数据无法显示问题咨询
React待办应用接口替换后数据不展示问题修复
问题背景
学习React过程中,最初使用json-server读取本地db.json存储待办数据,访问localhost:3000/todos接口时应用运行正常,效果如下:
初始db.json内容如下:
{ "todos": [ { "id": 1, "title": "bath", "done": "false" } ] }
后续改用MySQL存储数据,通过PHP编写接口查询todos表返回JSON格式数据,PHP代码如下:
<?php header('Content-Type: application/json; charset=utf8'); include("koneksi.php"); $query=mysqli_query($con,"SELECT * FROM todos"); //data array $array=array(); while($data=mysqli_fetch_assoc($query)) $array[]=$data; echo json_encode($array); ?>
访问PHP接口可正常返回如下JSON内容:
[{"id":"1","title":"bath","done":"false"}]
将前端fetch请求地址从json-server接口替换为PHP接口地址后,页面待办数据无法展示,控制台无报错。前端TodoList组件代码如下:
const TodoList = ({isRefresh, setRefresh}) => { const [todos, setTodos] = useState([]); useEffect(() => { // memanggil API untuk mengambil data todos if (isRefresh) { fetch("http://localhost:3000/todos") .then((res) => { return res.json(); }) .then((data) => { setRefresh(false) // ketika Rest API sukses, simpan data dari response ke dalam state lokal setTodos(data); }) .catch((err) => { setRefresh(false) if (err.name === "AbortError") { console.log("fetch aborted."); } }); } }, [isRefresh, setRefresh]);
问题根因
该问题不是接口返回JSON结构差异导致的,核心原因有两个:
- 跨域(CORS)拦截:React前端服务和PHP服务运行端口不一致(比如React默认跑在3000端口,PHP服务通常跑在80/8080端口),浏览器默认拦截不同源的接口请求。而原有fetch的catch块只处理了
AbortError类型的错误,跨域、网络类错误没有打印日志,所以控制台看不到报错,请求未拿到返回值自然无法渲染数据。 - 逻辑排查点:需要确认替换接口后,
isRefresh状态的初始值和触发逻辑正常,useEffect内的请求逻辑仅在isRefresh为true时才会执行,如果初始值为false且没有触发刷新的动作,请求根本不会发送。
注:两个接口返回的数据确实存在微小差异:json-server返回的id是数字类型,PHP返回的id是字符串类型,但该差异不会导致数据完全不展示,仅会影响后续依赖id做严格相等判断的逻辑。
修复方案
按以下步骤操作即可解决问题:
- 给PHP接口添加跨域允许头,修正charset配置,修改后的PHP代码如下:
<?php // 配置跨域允许,*表示允许所有源,生产环境建议替换为前端实际域名,本地调试可以写http://localhost:3000 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type"); // 修正charset为标准写法utf-8 header('Content-Type: application/json; charset=utf-8'); include("koneksi.php"); $query=mysqli_query($con,"SELECT * FROM todos"); $array=array(); while($data=mysqli_fetch_assoc($query)) { // 可选:把id转为数字类型,和json-server返回类型保持一致,避免后续严格判断出错 $data['id'] = (int)$data['id']; $array[]=$data; } echo json_encode($array); ?>
- 补全前端fetch的错误捕获逻辑,方便后续排查问题,修改catch块代码:
.catch((err) => { setRefresh(false) if (err.name === "AbortError") { console.log("fetch aborted."); } else { console.error("接口请求失败:", err); } });
- 将fetch方法中的请求地址替换为PHP接口的实际访问地址,确认地址可正常访问、返回JSON内容。
- 检查页面初始化逻辑,保证组件首次加载时
isRefresh值为true,触发请求发送。
内容的提问来源于stack exchange,提问作者Rin
相关产品推荐
相关产品推荐

