React useEffect首次渲染数据返回undefined问题求助
React useEffect获取数据时序问题分析与解决
这其实不是代码错误,而是React组件渲染和useEffect执行的正常时序问题,具体拆解如下:
- 首次渲染时:组件初始化时
data的初始值是你通过useState([])设置的空数组,所以此时console.log(data)输出的是[]。 - useEffect执行时机:
useEffect钩子是在组件首次渲染完成后才触发,里面的异步请求需要时间完成,在请求结束前,data会一直保持初始值。 - 状态更新触发重渲染:当axios请求完成、调用
setData(res.data)后,组件会因为状态更新重新渲染,此时data才会变成接口返回的{users: Array(5), id_usuario_logado: 25},后续的console.log也会输出这个值。
如果你是因为在首次渲染时尝试访问data的属性(比如data.users)而报错,那是因为初始data是数组,没有对应的属性,这里给你几个解决办法:
解决方案
1. 让初始状态匹配接口返回结构
把初始useState的设置改成和接口返回一致的结构,避免属性访问错误:
const [data, setData] = useState({ users: [], id_usuario_logado: null })
2. 用条件渲染判断数据是否就绪
在使用data的地方加判断,确保数据存在后再渲染:
return ( <div> {data.users?.map(user => ( <div key={user.id}>{user.name}</div> ))} </div> )
这里用了可选链操作符?.,如果data.users不存在会直接返回undefined,不会报错。
3. 添加加载状态提示
加个加载状态,在请求完成前显示加载提示,提升用户体验:
const [data, setData] = useState({ users: [], id_usuario_logado: null }) const [loading, setLoading] = useState(true) useEffect(() => { const fetchData = async () => { try { const res = await axios.get("http://localhost:3001/homeFeed") setData(res.data) } catch(err) { console.log(err) } finally { setLoading(false) } } fetchData() }, []) if (loading) { return <div>加载中...</div> } return ( <div> {data.users.map(user => ( <div key={user.id}>{user.name}</div> ))} </div> )
补充说明
控制台里出现两次[]是因为React开发模式下的严格模式会触发两次初始渲染,这是正常的,生产环境下只会出现一次初始值输出。
内容的提问来源于stack exchange,提问作者amorim
相关产品推荐
相关产品推荐

