如何在下拉选择后将映射值传递至React组件的State属性
我来帮你排查这个问题~核心原因其实很明显,咱们一步步拆解:
首先,你用来渲染「Account Head」的<label>标签是非交互表单控件,它既没有onChange事件触发能力,也无法通过value属性绑定组件state,这直接导致head_of_account永远无法被更新到state中,自然提交时是空值。
下面是具体的修复方案,顺带优化一些潜在的逻辑问题:
1. 替换无效控件,同步redux数据到state
既然journal1是根据选中的code获取的账户信息,我们需要在redux数据更新时,自动把head_of_account同步到组件state里。在类组件中可以用componentDidUpdate监听props变化:
componentDidUpdate(prevProps) { // 当journal1从redux更新时,同步head_of_account到state if (prevProps.journal1 !== this.props.journal1 && this.props.journal1.length > 0) { this.setState({ head_of_account: this.props.journal1[0].head_of_account }); } }
然后把原来的<label>替换成只读输入框(如果不需要用户修改的话),或者普通文本:
<p><label className="masterfileadd-text"> Account Head : <input type="text" value={this.state.head_of_account} className="jtextbox3" readOnly // 不需要用户修改就保留这个属性 /> </label></p>
2. 优化Select的事件触发逻辑
你现在给Select加了onClick={this.sendData},会导致每次点击下拉框(哪怕没选新值)都调用getCode,完全没必要。建议把getCode逻辑合并到现有的onChange方法中:
onChange = event => { const { name, value } = event.target; this.setState({ [name]: value }, () => { // 仅当code变化时,调用getCode获取对应账户信息 if (name === 'code') { const journal2 = { code: this.state.code }; this.props.getCode(journal2); } }); };
然后删掉Select上的onClick事件,顺便给列表项加上key(React列表渲染的最佳实践):
<select value={this.state.code} onChange={this.onChange} name="code" className="jtextbox2"> {this.props.journal.map(journal => { return <option key={journal.code} value={journal.code}>{journal.code}</option> })} </select>
3. 修复componentDidMount的逻辑问题
你在componentDidMount里先调用getData(),立刻就调用getCode,但此时getData可能还没完成,state里的code是空值,会导致无效请求。可以改成等待getData完成后再处理:
componentDidMount() { this.props.getData().then(() => { // 如果journal有数据,设置第一个code为默认值 if (this.props.journal.length > 0) { const defaultCode = this.props.journal[0].code; this.setState({ code: defaultCode }, () => { const journal2 = { code: this.state.code }; this.props.getCode(journal2); }); } }); }
(前提是你的getData方法返回Promise,如果没有的话,可以在componentDidUpdate里监听journal的变化来处理)
4. 其他小问题修复
- 你把
className写成了classname(小写的n),需要修正,否则样式不会生效 - form里有多余的
</label></p>标签,需要删除以避免DOM结构错误 - submit按钮上的
onChange={this.onChange}是多余的,直接删掉即可
修改后的render部分示例:
render() { return ( <div className="masterfile-add"> <form className="masterfileadd-form"> <p> <label className="masterfileadd-text"> Code : <select value={this.state.code} onChange={this.onChange} name="code" className="jtextbox2"> {this.props.journal.map(journal => { return <option key={journal.code} value={journal.code}>{journal.code}</option> })} </select> </label> </p> <p> <label className="masterfileadd-text"> Account Head : <input type="text" value={this.state.head_of_account} className="jtextbox3" readOnly /> </label> </p> <p className="jButton"> <input type="submit" value="Submit" onClick={this.onCreate} className="jButtonAdd" /> </p> </form> </div> ) }
这样修改后,选择code时会自动拉取对应的账户信息并同步到state,提交时head_of_account就不会是空值啦!
内容的提问来源于stack exchange,提问作者yash b

