React中Fetch数据存入State后渲染对象报错的技术求助
解决React中“Objects are not valid as a React child”错误
嘿,这个问题我太熟了!咱们先搞懂为啥会报错,再一步步改好代码~
错误原因拆解
你从API拿到的res.results[0]是单个用户对象(包含gender、name、email等一堆键值对),然后把它存在了data状态里,接着直接在JSX里写{data}——但React根本不知道怎么渲染一个对象啊!它只能渲染字符串、数字、React元素或者数组这类能直接展示的内容,所以才会抛出那个让人头大的错误。
修复方案&修改后的代码
咱们分两步调整:
1. 调整初始状态
因为你要存的是单个用户对象,把初始状态从数组[]改成null或者空对象{}更合理,逻辑上更贴合场景。
2. 渲染具体字段而非整个对象
在JSX里,先判断data是否存在(避免初始状态下访问属性报错),然后逐个取出对象里的字段来展示,比如姓名、邮箱、头像这些。
修改后的完整代码:
import { useState } from 'react' export default function Test(){ // 初始状态设为null,匹配单个用户对象的场景 const [data, setData] = useState(null); const getInfo = async () =>{ try { const response = await fetch('https://randomuser.me/api'); if(response.status === 200){ const res = await response.json(); // 这里res.results[0]是单个用户对象,赋值给data没问题 setData(res.results[0]); }else{ throw new Error('Unable to fetch data') } } catch (err) { // 加上错误捕获,避免网络问题导致页面崩溃 console.error(err.message); } } return( <div> <button onClick={getInfo}>fetch data</button> {/* 条件渲染:只有data存在时才展示用户信息 */} {data && ( <div style={{marginTop: '16px', padding: '16px', border: '1px solid #eee'}}> <h3>{data.name.first} {data.name.last}</h3> <p>📧 邮箱: {data.email}</p> <p>📞 电话: {data.phone}</p> <p>⚧️ 性别: {data.gender}</p> <img src={data.picture.medium} alt={`${data.name.first}的头像`} style={{borderRadius: '50%'}} /> </div> )} </div> ) }
额外场景:如果要存储多个用户数组
要是你想请求多个用户(比如把API改成https://randomuser.me/api?results=5),那初始状态用数组[]是对的,这时候渲染要通过map遍历数组:
import { useState } from 'react' export default function Test(){ // 初始状态用数组,存储多个用户 const [data, setData] = useState([]); const getInfo = async () =>{ try { const response = await fetch('https://randomuser.me/api?results=5'); if(response.status === 200){ const res = await response.json(); setData(res.results); // 这里是用户数组 }else{ throw new Error('Unable to fetch data') } } catch (err) { console.error(err.message); } } return( <div> <button onClick={getInfo}>fetch 5 users</button> {/* 数组长度大于0时渲染列表 */} {data.length > 0 && ( <div style={{marginTop: '16px', display: 'flex', gap: '16px', flexWrap: 'wrap'}}> {data.map((user, index) => ( <div key={index} style={{padding: '16px', border: '1px solid #eee', borderRadius: '8px'}} > <h4>{user.name.first} {user.name.last}</h4> <p>邮箱: {user.email}</p> <img src={user.picture.thumbnail} alt={`${user.name.first}的头像`} style={{borderRadius: '50%'}} /> </div> ))} </div> )} </div> ) }
内容的提问来源于stack exchange,提问作者botit
相关产品推荐
相关产品推荐

