重述:
我有一个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>
答案 0 :(得分:0)
1)你应该在componentDidMount
调用你的数据库请求,因为componentWillMount还没有访问dom的权限。
2)您可以使用componentWillUpdate
,以便检查是否从表单获取有效数据,和/或根据特定情况停止重新呈现组件。
答案 1 :(得分:0)
如果FormElement的键是不会更改的id,则不应卸载该元素,并在父级重新加载时再次装入该元素。您确定每次键入字段时都会调用componentWillMount方法吗?
如果每次键入时重新安装FormElement,您键入的内容也会消失。
答案 2 :(得分:0)
FormElements的数量是动态的吗?如果不是,我建议为父母中的每个FormElements分别设置一个州。然后,您只需要刷新已更改的元素。
更好的方法是使用redux-form来管理redux存储中的表单状态。每个FormElement都在商店中订阅它自己的状态,因此redux只刷新需要更改的那个。