React自定义Input组件输入值总是滞后一步,请问正确实现方式是什么?
问题诊断
你的代码问题出在React状态更新的异步特性上:
- React的状态更新是异步批量执行的,调用
setValue(e.target.value)后,当前函数作用域内的value还是本次渲染的旧值,React会在下一次渲染才会更新value的值,所以你紧接着传给父组件的value永远滞后一次输入。 - 同时你的Input组件同时在内部和父组件维护两份输入状态,不符合React受控组件的设计规范,后续也容易出现状态不同步的问题。
标准实现方案
React Input组件分受控、非受控两种实现,最常用的是受控组件,状态完全由父组件管理,组件本身只做props透传:
1. 修复后的Input组件代码
import React from 'react'; function Input(props) { const { type, className, placeholder, value, onChange } = props; return ( <div className='input-group mb-3'> <input onChange={onChange} type={type ?? 'text'} value={value ?? ''} className={className ?? 'form-control'} placeholder={placeholder ?? ''} /> </div> ); } export default Input;
2. 修复后的App组件代码
import React, { useState } from 'react'; import Input from './components/Input/Input'; function App() { const [inputValue, setInputValue] = useState(''); function handleInputChange(e) { // 直接从事件对象获取最新输入值 const currentValue = e.target.value; setInputValue(currentValue); console.log(currentValue); } return ( <div className='container'> <div className='row'> <Input value={inputValue} onChange={handleInputChange} /> <span>{inputValue}</span> </div> </div> ); } export default App;
临时修复方案(不推荐,仅适配你现有逻辑)
如果不想改动整体结构,只需要把Input组件中传给父组件的参数替换为事件对象上的最新值即可:
// Input.js 仅修改handleChange方法 let handleChange = (e) => { const newValue = e.target.value; setValue(newValue); // 不传旧的state value,直接传最新拿到的值 props.onChange(newValue); };
内容的提问来源于stack exchange,提问作者Okay Beydanol
相关产品推荐
相关产品推荐

