React组件接收props未渲染,刷新页面后传入的用户数组为空
问题根因
- App组件中
users状态初始值为空数组[],调用axios拉取用户数据是异步操作,不会阻塞组件的首次渲染流程,首次渲染时users还是初始空值 - ListComponent内的
useEffect依赖项为空数组,只会在组件首次挂载完成后执行一次,执行时机早于接口请求返回、setUsers触发状态更新的时机,因此打印的是空数组 - 修改代码触发热重载时,组件不会完全重新挂载,此时
users已经是请求完成后的值,所以可以正常显示内容;刷新页面相当于应用全量重新初始化,就会出现拿空数组的问题
解决方案
方案1:更新useEffect依赖项
给ListComponent的useEffect添加props.users作为依赖,数组更新时会自动重新执行useEffect,拿到最新值:
const ListComponent = (props) => { React.useEffect(()=>{ console.log(props.users); // 接口返回后会二次执行,打印最终的用户数组 },[props.users]) // 新增props.users作为依赖项 }
方案2:增加加载状态判断,请求完成后再渲染组件
在App组件中新增加载状态,避免空值阶段渲染ListComponent:
const [users,setUsers] = React.useState([]); const [loading, setLoading] = React.useState(true); React.useEffect( () => { async function fetchData() { await axios.get('/api/users/') .then(response => { setUsers(response.data); setLoading(false); }); } fetchData(); } , []); return ( // 加载阶段显示提示,请求完成后再渲染列表组件 loading ? <div>加载中...</div> : <ListComponent users={users} /> );
方案3:直接渲染无需useEffect包裹
如果只是要渲染用户列表,不需要在useEffect中处理数据,直接取props.users渲染即可,状态更新后组件会自动重新渲染最新内容:
const ListComponent = (props) => { return ( <ul> {props.users.map(user => <li key={user.id}>{user.name}</li>)} </ul> ) }
内容的提问来源于stack exchange,提问作者Oussama Eddahri
相关产品推荐
相关产品推荐

