React父组件中表单onSubmit正确用法及组件间传值问题
React无状态子组件表单onSubmit不触发的问题分析与解决
嘿,我帮你揪出问题根源啦!核心问题出在React组件的命名规则上,顺便还有个小的状态更新逻辑错误,咱们一步步说:
为什么onSubmit不触发?
你写的无状态组件是小写开头的todoListForm,但在App组件里调用的却是<TodoListForm />(大写开头)。在React的规则里:
- 大写开头的标签会被识别为自定义组件
- 小写开头的标签会被当成原生HTML元素处理
所以你的代码里,<TodoListForm />根本没有渲染你写的自定义组件,而是被当成了一个不存在的原生标签,表单的onSubmit自然没绑定到你定义的handleSubmit函数,点击提交当然没反应!
另外你的handleChange里的状态更新也有问题:
this.setState({ value: this.state.value, listItemValue: value });
这里value字段完全没更新,还是原来的旧值,应该改成同步更新两个状态字段。
修正后的完整代码
先把无状态组件改成大写开头,再修复状态更新和属性传递的小问题:
class App extends Component { constructor(props) { super(props); this.state = { value: '', listItemValue: props.value || '', todoItems: [] }; this.handleSubmit = this.handleSubmit.bind(this); this.handleChange = this.handleChange.bind(this); } handleChange(event) { const value = event.target.value; // 同步更新两个状态字段 this.setState({ value, listItemValue: value }); } handleSubmit(event) { alert('A name was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <div className="App"> <h1>Todo List</h1> <TodoListForm name="todo" onSubmit={this.handleSubmit} handleChange={this.handleChange} value={this.state.listItemValue} /> <TodoList /> </div> ); } } // 无状态组件改为大写开头的TodoListForm const TodoListForm = (props) => { return ( <form onSubmit={props.onSubmit}> <label htmlFor='todo-list-item'>Add a Todo</label> {/* 匹配父组件传递的value属性 */} <input name={props.name} value={props.value} onChange={props.handleChange} type="text" placeholder='Enter a todo ...' /> <button type="submit" className='TodoListForm__Button'>add</button> </form> ) }
有状态父组件+无状态子组件传递输入值的最佳实践
- 父组件负责维护状态,通过
props把状态值和状态更新方法(比如handleChange)传给子组件 - 子组件作为受控组件,input的
value绑定父组件传的props.value,onChange调用父组件的方法更新状态 - 表单的
onSubmit同样通过props接收父组件的处理函数,绑定到子组件的form标签上
这样就能完美实现「父组件管状态,子组件管UI和事件触发」的分工啦。
内容的提问来源于stack exchange,提问作者TYPOI
相关产品推荐
相关产品推荐

