React出现受控输入转非受控警告及输入值联动问题如何解决
问题根因与修复方案
1. 两个输入框内容同步问题
- handleChange逻辑错误:无论哪个输入框触发更新,都同时给
firstName、seconfName(拼写错误)赋值同一个输入值,导致两个字段永远保持一致 - 未通过输入框的
name属性区分要更新的字段,你给input设置的name属性完全没有被用到
2. 受控组件转非受控警告问题
- setState时直接覆盖了整个
person对象,没有保留原有字段:原来person下的profession、city等10+字段在setState后会全部丢失,变为undefined,如果后续你添加了绑定这些字段的输入框,就会因为value从初始空字符串变为undefined,触发受控转非受控的警告 secondName字段拼写错误:handleChange里写的是seconfName,和state里定义的secondName不一致,导致该字段永远无法被正确更新,后续逻辑依赖该字段时也会出现异常
修复后的代码
App组件修正
// 别忘了导入Component import { Component } from 'react'; import MyForm from './Components/MyForm'; import uniqid from "uniqid"; class App extends Component { constructor (props) { super(props); this.state = { person: { firstName : '', secondName : '', profession : '', city: '', state: '', phone:'', email: '', jobTitle: '', employer: '', startDate: '', endDate: '', schoolName: '', schoolLocation: '', gradStartDate: '', gradEndDate: '', id: uniqid() }, resume:[] } } handleChange = (event) => { const fieldName = event.target.name; const fieldValue = event.target.value; this.setState({ person : { // 展开原有person对象,保留其他字段不丢失 ...this.state.person, // 用name属性匹配要更新的对应字段 [fieldName]: fieldValue } }); } handleSubmit = (event) => { event.preventDefault(); return alert(this.state.person.firstName + this.state.person.secondName) } render () { const { person, resume} = this.state; return ( <div> <MyForm person = {person} resume = {resume} handleChange={this.handleChange} handleSubmit={this.handleSubmit}/> </div> ) } } export default App;
MyForm组件修正(单独存放在./Components/MyForm.js中)
import React from 'react'; class MyForm extends React.Component { render() { const {person, handleChange,handleSubmit } = this.props; return ( <div> <form onSubmit = { handleSubmit }> <div> <label> First Name: <input type="text" value = { person.firstName } onChange = { handleChange } name="firstName" /> </label> </div> <div> <label> Second Name: <input type="text" value = { person.secondName } onChange = { handleChange } name="secondName" /> </label> </div> <input type ="submit" value = "Submit" /> </form> </div> ) } } export default MyForm;
补充说明
后续新增其他输入框时,只要给input设置和state.person下字段名完全一致的name属性,不需要修改handleChange逻辑就能直接复用。
内容的提问来源于stack exchange,提问作者Joseph Mariga
相关产品推荐
相关产品推荐

