React中子组件单选按钮表单onChange时向父组件传值的问题
问题描述
在React中需要将子组件的表单数据实时传递给父组件(表单内容变化时立即传值),目前使用onChange事件处理,但遇到问题:首次点击单选按钮时无数据传递,点击另一个单选按钮时传递的是上一次选中的值。
父组件(App.js)
import React from 'react'; import Form from './Form'; function App() { function getData (data) { console.log (`coming from the parent component ${data}`) } return ( <div className="App"> <Form onSubmit={getData}/> </div> ); } export default App;
子组件(Form.js)
import React from 'react'; function Form(props) { const [name, setName] = React.useState(''); const [answer, setAnswer] = React.useState(''); function handleChange(event) { setName(event.target.value); setAnswer(event.target.value); props.onSubmit(answer); } console.log(answer); return ( <> <form> <input type="text" value={name} onChange={handleChange} /> <br /> <input onChange={handleChange} type="radio" value="Radio 1" name="paka" />{'Radio 1'} <input onChange={handleChange} type="radio" value="Radio 2" name="paka" />{'Radio 2'} <input onChange={handleChange} type="radio" value="Radio 3" name="paka" />{'Radio 3'} <input onChange={handleChange} type="radio" value="Radio 4" name="paka" />{'Radio 4'} <br /> </form> </> ); } export default Form;
问题原因
React的useState更新是异步的,调用setAnswer(event.target.value)后,answer变量不会立即更新为新值。此时执行props.onSubmit(answer),传递的是更新前的旧值:
- 首次点击单选按钮时,
answer初始值为空字符串,所以父组件收到空值; - 第二次点击时,
answer刚完成第一次更新,传递的是第一次选中的值,以此类推。
解决方案
方案1:直接传递当前输入值
不需要依赖answer状态,直接把event.target.value传给父组件,就能拿到最新的输入值:
function handleChange(event) { const newValue = event.target.value; setName(newValue); setAnswer(newValue); props.onSubmit(newValue); // 直接传递最新输入值 }
方案2:用useEffect监听状态变化
如果必须依赖answer状态的值,可以使用useEffect监听answer的变化,当状态更新后再通知父组件:
import React, { useEffect } from 'react'; function Form(props) { const [name, setName] = React.useState(''); const [answer, setAnswer] = React.useState(''); function handleChange(event) { const newValue = event.target.value; setName(newValue); setAnswer(newValue); } // 监听answer状态变化,更新后通知父组件 useEffect(() => { props.onSubmit(answer); }, [answer, props.onSubmit]); console.log(answer); // 其余返回代码保持不变 }
额外优化建议
- 文本框和单选按钮共用同一个
handleChange会导致文本框输入时也更新answer状态,若这不是预期行为,建议分开处理不同类型的输入; - 父组件的回调函数命名为
onSubmit容易和表单原生onSubmit事件混淆,建议改为更清晰的名称(比如onFormDataChange),子组件同步修改调用逻辑。
内容的提问来源于stack exchange,提问作者Hiran Kaushal
相关产品推荐
相关产品推荐

