每次一个孩子更新时,React重新渲染整个地图

时间:2017-03-21 18:09:24

标签: javascript forms reactjs

重述:

我有一个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>

3 个答案:

答案 0 :(得分:0)

1)你应该在componentDidMount调用你的数据库请求,因为componentWillMount还没有访问dom的权限。

2)您可以使用componentWillUpdate,以便检查是否从表单获取有效数据,和/或根据特定情况停止重新呈现组件。

答案 1 :(得分:0)

如果FormElement的键是不会更改的id,则不应卸载该元素,并在父级重新加载时再次装入该元素。您确定每次键入字段时都会调用componentWillMount方法吗?

如果每次键入时重新安装FormElement,您键入的内容也会消失。

答案 2 :(得分:0)

FormElements的数量是动态的吗?如果不是,我建议为父母中的每个FormElements分别设置一个州。然后,您只需要刷新已更改的元素。

更好的方法是使用redux-form来管理redux存储中的表单状态。每个FormElement都在商店中订阅它自己的状态,因此redux只刷新需要更改的那个。