React使用onChange更新状态时address失效textarea显示undefined如何解决
问题根源
- 初始状态中
users.address被定义为空字符串,但你在渲染textarea时尝试读取addr.street、addr.city、addr.zipcode三个对象属性,字符串不存在这些属性,初始渲染就会返回undefined。 - 接口返回的
address是包含street/city/zipcode的对象,但你在onChange时直接把textarea的输入值作为字符串覆盖给address字段,覆盖后address变成普通字符串,再次读取属性依然是undefined,所以输入后会显示undefined undefined undefined。
解决方案
根据你的需求选择以下两种方案之一:
方案1:将address作为完整字符串存储(适配单个textarea输入)
如果你不需要保留address的对象结构,只需要存完整地址文本,修改两处代码即可:
- 调整
getOneUser方法,把接口返回的address对象拼接为字符串再存入state:
async getOneUser(){ try{ const {id} = this.props.match.params; const res = await fetch(`http://localhost:3003/users/${id}`); const data = await res.json(); const {name, address} = data; // 把address对象拼接为字符串 const addressStr = `${address.street}, ${address.city}, ${address.zipcode}` this.setState({users: {name, address: addressStr}}, () => console.log(this.state)); }catch(err){ console.error(err.message); } }
- 修改textarea的value属性,直接读取address字符串,不需要拆分属性:
<textarea name='address' value={this.state.users.address} onChange={e => this.onChangeHandler(e)} className="form-control" placeholder="Address" id="floatingTextarea"> </textarea>
方案2:保留address的对象结构
如果你需要继续存储address为包含street/city/zipcode的对象,建议拆分为三个输入框分别对应三个属性,修改如下:
- 调整初始state的address结构:
this.state = { users: { name: '', address: { street: '', city: '', zipcode: '' }, }, }
- 修改onChangeHandler,适配嵌套对象更新:
onChangeHandler(e){ const {name, value} = e.target; // 如果是address相关的字段,更新嵌套对象 if(['street', 'city', 'zipcode'].includes(name)){ this.setState({ users: { ...this.state.users, address: { ...this.state.users.address, [name]: value } } }) }else{ this.setState({ users: {...this.state.users, [name]:value} }); } };
- 渲染部分拆分三个输入框:
<input type='text' name='name' value={this.state.users.name} onChange={this.onChangeHandler} className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" /> <input type='text' name='street' value={this.state.users.address.street} onChange={this.onChangeHandler} className="form-control" placeholder="街道" /> <input type='text' name='city' value={this.state.users.address.city} onChange={this.onChangeHandler} className="form-control" placeholder="城市" /> <input type='text' name='zipcode' value={this.state.users.address.zipcode} onChange={this.onChangeHandler} className="form-control" placeholder="邮编" />
内容的提问来源于stack exchange,提问作者Ajay Singh Rajput
相关产品推荐
相关产品推荐

