React点击按钮需两次才能向API正确提交输入值的修复方法
问题根因
代码里有两个核心逻辑错误,直接导致首次点击传空值、逻辑执行错位:
- React的
useState状态更新是异步批处理的,单次渲染生成的函数闭包里,状态值是固定常量。调用setInputValue不会立刻修改当前作用域里的inputValue变量,必须等组件重渲染完成,新生成的闭包才能拿到更新后的值。如果提交函数捕获的是旧渲染周期的状态,拿到的就是初始空字符串。 axios.post是异步请求,你调用API()发请求后立刻同步判断apiData.is_active,这时候请求还没返回,setApiData根本没执行,拿到的永远是初始空值,判断逻辑完全不生效。第一次请求返回后apiData才被更新,第二次点击才能拿到上一次的返回结果,自然就出现“第一次不对第二次对”的错位。
修复方案
- 把提交逻辑改为
async/await写法,等待接口返回结果后再执行跳转、错误提示逻辑,不要依赖状态更新做同步判断。 - 移除无意义的独立
apiData状态:接口返回值只在当前提交流程里使用,不需要全局存到状态中,减少不必要的重渲染。 - 把按钮的
type从submit改为button,避免后续外层包裹表单时触发默认页面刷新,导致状态丢失。 - 增加请求异常捕获,避免网络错误时页面无反馈。
修复后的完整代码如下:
const InputEmail = () => { const navigate = useNavigate() const [inputValue, setInputValue] = useState('') const [isError, setIsError] = useState(false) const handleSubmit = async () => { try { // 等待接口返回后再执行后续逻辑 const response = await axios.post(url, { email: inputValue }) const apiData = response.data console.log('提交的邮箱:', inputValue, '接口返回:', apiData) if (apiData.is_active) { localStorage.setItem('email', inputValue) navigate("/assessment") setIsError(false) } else { setIsError(true) } } catch (err) { setIsError(true) } } return ( <div className='main'> <FormControl> <h2 className='text'>Registered Email address</h2> <Input id='email' type='email' value={inputValue} onChange={e => setInputValue(e.target.value)} /> { isError ? <FormHelperText color='red'>Email not found. Please enter registered email</FormHelperText> : null } <Button mt={4} colorScheme='teal' type='button' onClick={handleSubmit} > Submit </Button> </FormControl> </div> ) }
内容的提问来源于stack exchange,提问作者deoxzy
相关产品推荐
相关产品推荐

