React的handleSubmit中如何用async await等待fetch完成后执行角色跳转
问题原因
fetch是异步API,调用后会立刻返回不会等待请求完成,你写在fetch外部的跳转逻辑会在请求刚发出时就执行,此时还没有拿到后端返回的用户数据。- React的
setCurrentUser状态更新也是异步的,就算在请求回调里执行了set操作,也无法在同一函数上下文中立刻拿到更新后的currentUser值。
解决方案1:async/await改写(推荐)
直接把handleSubmit改为异步函数,用await等待请求完成后再执行跳转逻辑,直接用接口返回的用户数据做角色判断,不需要依赖更新后的状态:
// 给函数添加async标识 async function handleSubmit(e) { e.preventDefault(); try { // 等待fetch请求完成拿到响应 const res = await fetch(`${process.env.REACT_APP_API}/login`, { credentials: 'include', headers: { 'Content-Type': 'application/json' }, method: 'POST', body: JSON.stringify({ email: email, password: password }), }); const userData = await res.json(); const user = userData.user; // 更新用户状态 setCurrentUser(user); // 直接用接口返回的用户数据判断跳转 user.role === 'admin' ? history.push('/admin') : history.push('/'); } catch (error) { console.error('FETCH ERROR:', error); } }
解决方案2:保持原有.then链式写法
不需要改写异步语法,只需要把跳转逻辑移到请求成功的回调里即可:
function handleSubmit(e) { e.preventDefault(); fetch(`${process.env.REACT_APP_API}/login`, { credentials: 'include', headers: { 'Content-Type': 'application/json' }, method: 'POST', body: JSON.stringify({ email: email, password: password }), }) .then((res) => res.json()) .then((userData) => { const user = userData.user; setCurrentUser(user); // 把跳转逻辑移到请求回调内部,拿到数据后再执行 user.role === 'admin' ? history.push('/admin') : history.push('/'); }) .catch((error) => console.error('FETCH ERROR:', error)); }
注意事项
不要尝试在
setCurrentUser执行后立刻读取currentUser的值,React的状态更新是批量异步执行的,同一函数上下文里的状态更新不会立刻生效,直接用接口返回的用户数据做判断是最稳妥的方案。
内容的提问来源于stack exchange,提问作者bob
相关产品推荐
相关产品推荐

