React中如何传递输入框当前值为bind参数?点击同步值失效问题
问题分析与解决方案
你的问题出在点击按钮时传递的是组件渲染时的旧state值,而不是输入框当前的实时内容。让我拆解一下问题:
你在父组件里用了this.setUserInputHandler.bind(this, this.state.input),这里的this.state.input是组件第一次渲染时的'initial',之后你在输入框里输入内容,这个绑定的参数并不会自动更新——因为bind是在渲染阶段就确定了参数值的,所以点击按钮时,你传递的始终是初始值,自然无法更新UserOutput的内容。
下面给你两种可行的解决方案:
方案一:使用Ref获取输入框实时值(非受控组件方式)
这种方式不需要实时维护state,点击按钮时直接从DOM获取输入框的最新值:
修改UserInput组件
因为UserInput是函数组件,我们可以用useRef来引用输入框元素:
import { useRef } from 'react'; // 记得导入useRef const UserInput = (props) => { // 创建一个ref关联到输入框 const inputRef = useRef(null); const handleButtonClick = () => { // 获取输入框当前的value const currentInputValue = inputRef.current.value; // 把值传给父组件的回调函数 props.click(currentInputValue); }; return ( <div className='UserInput'> <input type='text' ref={inputRef} /> <button onClick={handleButtonClick}>Set</button> </div> ); };
修改父组件的事件绑定
不需要再绑定参数了,直接传递函数引用即可:
// 父组件render里的UserInput改为: <UserInput click={this.setUserInputHandler} />
这样点击按钮时,就能拿到输入框的实时值,更新state后,UserOutput就会同步显示最新内容了。
方案二:受控组件(实时维护state,点击按钮确认)
如果你想让输入框的值和state保持同步,同时点击按钮再触发更新(比如做额外校验),可以用受控组件的方式:
修改父组件
添加一个临时state存储输入框的实时内容,点击按钮时把它赋值给用于显示的state:
class App extends Component { state = { input: 'initial', tempInput: 'initial' // 存储输入框实时内容 }; // 实时更新临时state handleInputChange = (e) => { this.setState({ tempInput: e.target.value }); } // 点击按钮时,把临时值赋值给显示用的state setUserInputHandler = () => { this.setState({ input: this.state.tempInput }); console.log('Value is', this.state.tempInput); } render() { return ( <div className="App"> <UserInput onChange={this.handleInputChange} currentValue={this.state.tempInput} click={this.setUserInputHandler} /> <UserOutput username={this.state.input} /> <UserOutput username={this.state.input} /> </div> ); } }
修改UserInput组件
让输入框成为受控组件,绑定value和onChange:
const UserInput = (props) => { return ( <div className='UserInput'> <input type='text' value={props.currentValue} onChange={props.onChange} /> <button onClick={props.click}>Set</button> </div> ); }
这种方式的好处是可以实时控制输入框的内容,比如做输入校验、限制长度等,点击按钮时再确认更新显示内容。
两种方案都能解决你的问题,根据你的实际需求选择即可~
内容的提问来源于stack exchange,提问作者Huseyn Mikayil
相关产品推荐
相关产品推荐

