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

为何首次点击Submit时代码返回空数组,二次提交才正常?

问题原因与解决方案

这是React里非常常见的useState异步更新特性导致的问题,我来给你讲清楚为啥会这样,以及怎么解决:

为什么首次点击会输出空数组?

React的useState状态更新是异步批量处理的,当你在onSubmit里调用setValues(data)时,React并不会立刻更新values的状态,而是把这个更新请求加入到更新队列中,等到当前渲染周期结束后,才会统一处理队列里的更新、更新组件状态并重新渲染。

所以你在setValues(data)之后立刻console.log(values),拿到的其实还是更新前的旧状态(也就是初始的空数组)。第二次点击时,values已经是第一次提交的结果了,这时候打印的就是上一次的正确数据,看起来像是“正常”了,但其实逻辑还是有问题的。

两种解决办法

办法1:直接使用表单提交的data参数

如果你只是需要在提交时打印或处理最新的表单数据,完全没必要等values状态更新,直接用onSubmit函数里的data参数就行,它就是实时的最新数据:

function App() {
  const {handleSubmit, register} = useForm()
  const [values, setValues] = useState([])
  const onSubmit = (data) => {
    setValues(data)
    console.log(data) // 直接用data,而不是values
  }
  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>
        <label>Enter Your Name</label>
        <input name='name' type='text' ref={register} placeholder='Name'/>
        <label>I'm a : </label>
        <select name="role" ref={register}>
          <option value="student">Student</option>
          <option value="teacher">Teacher</option>
        </select>
        <button type='submit'>Submit</button>
      </form>
    </div>
  );
}

办法2:用useEffect监听values的变化

如果你确实需要在values状态更新完成后执行某些操作(比如根据新值发起请求),可以使用useEffect钩子,把values加入依赖数组,这样每次values更新后都会触发回调:

import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';

function App() {
  const {handleSubmit, register} = useForm()
  const [values, setValues] = useState([])
  
  // 监听values变化,更新后执行操作
  useEffect(() => {
    if (Object.keys(values).length > 0) { // 避免初始空数组触发
      console.log(values)
      // 这里可以放需要在values更新后执行的逻辑
    }
  }, [values])

  const onSubmit = (data) => {
    setValues(data)
  }
  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>
        <label>Enter Your Name</label>
        <input name='name' type='text' ref={register} placeholder='Name'/>
        <label>I'm a : </label>
        <select name="role" ref={register}>
          <option value="student">Student</option>
          <option value="teacher">Teacher</option>
        </select>
        <button type='submit'>Submit</button>
      </form>
    </div>
  );
}

总结

记住React的状态更新是异步的,不要在调用状态更新函数(比如setValues)之后立刻去读取状态值,要么直接用更新时的数据源(比如这里的data),要么用useEffect监听状态变化来处理后续逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:02:38