React中Axios POST请求首次报401 Unauthorized,二次请求正常求助
登录表单首次提交401、二次提交正常的问题排查与修复
问题根源
你在onSubmit中先调用setEmailValue/setPasswordValue更新状态,随后立刻执行postLogin。但React的useState更新是异步的,第一次触发postLogin时,emailValue和passwordValue还停留在初始空值状态,导致请求发送的参数无效,后端返回401。第二次点击时,状态已完成更新,参数正确,因此请求成功。
另外,你完全不需要额外维护emailValue和passwordValue状态——react-hook-form已经内置了表单数据管理能力,直接使用提交时的表单数据即可。
修复后的代码
import { useState } from 'react' import axios from 'axios' import env from 'react-dotenv' import { useForm } from 'react-hook-form' import { useHistory } from 'react-router-dom' function Login() { const history = useHistory() const [error, setError] = useState(false) const [errorMessage, setErrorMessage] = useState('') const { register, handleSubmit } = useForm() const onSubmit = async (formData) => { try { const response = await axios.post(`${env.API_URL}/login`, { email: formData.email, password: formData.password, }) setError(false) localStorage.setItem('evelencia_login', JSON.stringify(response.data)) history.push('/status') } catch (err) { setError(true) setErrorMessage(err.response?.data?.message || '登录失败') } } return ( <div> <form onSubmit={handleSubmit(onSubmit)}> <label> Email :<input type='email' {...register('email', { required: true })} /> </label> <label> Password :<input type='password' {...register('password', { required: true })} /> </label> <input type='submit' value='Connexion' /> {error && <p>{errorMessage}</p>} </form> </div> ) } export default Login
关键优化点
- 移除冗余的
emailValue/passwordValue状态,直接使用react-hook-form提交时的formData参数,彻底规避异步状态更新的时序问题。 - 改用
async/await写法,代码逻辑更清晰直观。 - 优化错误处理:提取后端返回的具体错误信息,避免直接存储Error对象,同时添加默认错误提示。
- 给表单字段添加
required规则,提前在前端完成基础校验,减少无效请求。
内容的提问来源于stack exchange,提问作者Eldau
相关产品推荐
相关产品推荐

