开发手记-前端发送请求返回数据为空
问题描述
发送请求获取到数据并传递给组件,但是组件第一次获取到的数据为空导致报错
猜测可能的原因
- react有一个机制会导致两次渲染
- axios异步请求,在没有去的结果前就返回
组件首次渲染时,数据还未到达,导致错误
解决
数据来自于组件自己发送的请求
可以在组件中使用 useState 来初始化数据,然后在 useEffect 中发送请求获取数据,并将数据更新到组件状态中
这样,组件首次渲染时就可以使用初始化的数据,而当请求返回数据后,组件会重新渲染并更新数据
加载动画在组件的渲染方法中,我们首先判断 data 是否为空,如果为空则显示 Loading...,否则将数据渲染到页面上。
重点在于1. 首先数据会有一个初始化值,不会报空错误,2. 数据更新后会重新渲染
function MyComponent(props) { const [data, setData] = useState(null); useEffect(() => { async function fetchData() { const result = await axios.get('api/data'); setData(result.data); } fetchData(); }, [props.data]); return ( <div> {data && <p>{data.title}</p>} </div> ); }
数据来自于父组件传值
- 使用 props 来获取父组件传递的数据,然后在子组件内部使用 && 运算符来做条件判断。如果数据为空,则不渲染相应的子组件,避免报错
但是这样做其实很简陋,如果需要监控父组件传过来的值得变化并同步更新到子组件中,就需要在useEffect
中监听父组件传递的数据变化
const { detailShow, detailClose, postDetail, commentList, sendRequest } = props; const [likeCount, setLikeCount] = useState(0); const [likeStatus, setLikeStatus] = useState('bi-hand-thumbs-up'); useEffect(() => { if (postDetail) { setLikeCount(postDetail.likeCount); setLikeStatus(postDetail.likeStatus ? 'bi-hand-thumbs-up-fill' : 'bi-hand-thumbs-up'); } }, [postDetail]);
- 如果单独只考虑确保在父组件发送的请求返回数据后再执行
set
,似乎无法解决这个问题
const handleSubmit = async (discussPostId: string) => { try { const response = await axios.post(`http://localhost:8079/community/comment/add/${discussPostId}`, { userId: cookie.get('userId'), entityType: 1, entityId: discussPostId, content: comment }, { headers: { 'Content-Type': 'application/json' }, withCredentials: true }); const code = response.data.code; if (code === 200 && commentRef.current) { commentRef.current.value = ''; setComment(''); alert('回帖成功'); refresh(); } } catch (error) { console.log('请求失败', error); } }
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/17309965.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步