React报错:Objects are not valid as a React child (found: [object Promise])
问题排查与解决
1. 组件不能标记为async
你把组件声明成了async function LobbyPage,但React组件的返回值必须是JSX元素(或null/undefined),而async函数默认返回Promise对象——这就是报错“found: [object Promise]”的直接根源。直接去掉async关键字即可。
2. 数据请求必须放在useEffect钩子中
当前代码里的axios请求直接写在组件顶层,会导致组件每次渲染都重复发起请求,既浪费资源又可能引发不必要的状态更新。需要把请求逻辑放到useEffect里,依赖项设为空数组确保只在组件挂载时执行一次:
import { useState, useEffect } from 'react'; export function LobbyPage(props) { const [data, setState] = useState(null); const [loading, setLoading] = useState(true); // 新增加载状态,处理初始渲染逻辑 useEffect(() => { axios.get("http://127.0.0.1:8000/api_shop/") .then(res => { setState(res.data); setLoading(false); // 请求完成后关闭加载状态 }) .catch(err => { console.error('请求失败:', err); setLoading(false); // 出错也要关闭加载状态,避免页面一直处于加载中 }); }, []); // 空依赖数组,仅组件挂载时执行一次请求
3. 处理data为null时的渲染逻辑
初始状态下data是null,直接调用data.map()会触发“Cannot read properties of null (reading 'map')”错误。结合新增的loading状态,做条件渲染:
return ( <> <CatNav /> <main> {loading ? ( <div>加载中...</div> // 加载状态提示 ) : data ? ( data.map((current) => ( <div key={current.id} className="card"> {/* 必须给列表元素加唯一key,比如后端返回的id */} <img src={current.photo} alt={current.name}/> {/* 替换alt为有意义的内容,比如商品名称 */} <div className="card-body"> <h5 className="card-title">{current.name}</h5> <p className="card-text">{current.desc}</p> <a href="#" className="btn btn-primary">查看详情</a> {/* 给按钮添加文本,提升可用性 */} </div> </div> )) ) : ( <div>暂无数据</div> // 数据为空时的提示 )} </main> </> ) }
额外注意事项
- 列表渲染必须给每个元素添加唯一
key属性,这是React的要求,能避免性能问题和控制台警告。 - 一定要处理请求失败的情况,通过
catch捕获错误并给出反馈,避免页面卡死在加载状态。 - 图片的
alt属性尽量使用与内容相关的文本,而非固定的“Nothing”,符合无障碍设计规范。
内容的提问来源于stack exchange,提问作者bl4z3rr666
相关产品推荐
相关产品推荐

