You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React函数组件使用Hooks时无法获取最新state状态如何解决?

问题根因

你遇到的问题核心来自两个疏漏:

  1. 校验逻辑仅在捕获到错误时更新errors状态,校验通过的分支没有清空之前存储的错误,导致合法输入时仍然显示旧的错误提示
  2. React的状态更新是异步的,调用setErrors后无法立即在同一作用域内拿到更新后的errors值,这也是你直接打印errors.length拿到旧值的原因

修复方案

不需要依赖useEffect监听状态来触发提交,直接让校验函数返回最新的校验结果即可,同时补全清空错误的逻辑:

  1. 修改validate函数,补充校验通过时清空错误的逻辑,同时直接返回错误列表
const validate = async () => {
  try  {
    await schema.validate(user, { abortEarly: false })
    // 校验通过,清空历史错误
    setErrors([])
    return []
  } catch(er){
    const errList = [...er.errors]
    setErrors(errList)
    return errList
  }
}
  1. 修改handleSubmit函数,直接使用validate返回的最新结果判断是否要提交,避免读取异步更新的状态
const handleSubmit = async (e) => {
  e.preventDefault()
  // 直接拿到最新的校验结果,不用读状态的errors
  const latestErrors = await validate()
  if(latestErrors.length === 0){
    alert("X")
    const response= await axios.post("https://reqres.in/api/login",user)
    console.log(response)
  }
}
  1. 移除你之前用来监听errors触发提交的useEffect,该逻辑会导致组件初始化时errors为空就触发一次无效的提交请求。

可选优化

你的Input组件统一用了type="text",密码输入框建议单独指定type="password"避免明文显示,修改调用处代码即可:

<Input type="password" name="password" onChange={handleInputChange} id="password" value={user.password} label="رمز عبور"/>

同时给Input组件的原生input标签绑定type属性:

<input type={this.props.type || "text"} onChange={this.props.onChange} name={this.props.name} id={this.props.id} className="form-control" value={this.props.value} />

内容的提问来源于stack exchange,提问作者bami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:57:03