【发布时间】:2017-03-21 18:09:24
【问题描述】:
改写:
我有一个 FormElements 数组。每次其中一个更改时,我都会将更新发送到父表单。此表单会更新 formData 的状态。
问题是表单中的地图重新渲染了所有的孩子。我需要的是只渲染一个更新的 FormElement。
这会导致性能问题,尤其是对于下拉菜单,它们必须在挂载时从数据库中获取所有可能的值。
代码很多,所以我会尝试在下面放一些相关的东西:
表单页面:
handleFormElementChange(id, value) {
var frm = this.state.formData;
var index=-1;
for(var i=0;i<frm.length;i++) {
if(frm[i].id==id) {
index=i;
break;
}
}
frm[index].value = value;
this.setState({formData: frm, selectedElementId: id});
}
渲染:(这是问题所在,重新渲染所有子节点)
const FormElements = ({formFields}) => (<div> {
formFields.map(formField => (<FormElement name={formField.name} key={(formField.id != undefined) ? formField.id : "1"} editable={formField.editable} selected={this.state.selectedElementId} value={formField.value} id={formField.id} type={formField.fieldType} handleChange={this.handleFormElementChange.bind(this)}/>)
)} </div>);
FormElement 页面:
componentWillMount() {
if(this.props.type == this.state.fieldTypesEnum.DROPDOWN) {
var self = this;
this.getDropdownVals(this.props.id, function(callback) {
self.setState({
dropdownVals: callback
});
});
}
}
onChange(e) {
this.props.handleChange(e.target.id, e.target.value);
}
渲染:
if(this.props.type == this.state.fieldTypesEnum.DROPDOWN) {
var self = this;
var MakeItem = function(item) {
return <option key={(item.ID != undefined) ? item.ID : "1"} value={item.ID}>{item.value}</option>;
};
let data = this.state.dropdownVals;
return (<div class="form-group">
<label for={this.props.id}>{this.props.name}:</label>
<select name={this.props.id} type={this.props.type} maxLength="20" class="form-control" disabled={!this.props.editable} id={this.props.id} value={this.state.isChecked} onChange={this.onChange} ref={(input) => { this.nameInput = input; }}>
{data.map(MakeItem)}
</select>
【问题讨论】:
-
debounce方法可能适用于此,如果您不希望您的 handleChange 方法如此快速地触发。这是reference -
有趣!它仍然不理想,因为每次更改字段时下拉菜单都会闪烁并重新填充
-
您从数据库中提取数据的方法是根据表单的值还是两者分开?
-
它使用表单字段 id,如果这是您所要求的
标签: javascript forms reactjs