2017-03-21 5 views
0

マップ全体を:が反応再レンダリングするたびに1子の更新言い換え

私はFormElementsとの配列を持っています。それらのうちの1つが変更されるたびに、私は更新を親フォームに送信します。このフォームは、formDataの状態を更新します。

フォームのマップがすべての子を再レンダリングするという問題があります。私が必要とするのは、更新されたFormElementだけをレンダリングすることです。

これは、マウント時にデータベースからすべての値を取得する必要がある、パフォーマンス上の問題を引き起こします(espciallyドロップダウン)。

あり多くのコードがありますので、私がしようとすると下ののrelaventのものを出してあげる:

フォームページ:

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

handleChangeメソッドを非常に速く起動させたくない場合は、 'debounce'メソッドをここに適用できます。ここには[参照](https://css-tricks.com/the-difference-between-throttling-and-debouncing/) –

+0

興味深い!フィールドが変更されるたびにドロップダウンが点滅して再投入されるため、まだ理想的ではありません – Wayneio

+0

フォームの値に応じてデータベースからデータを取り出す方法、または両方が別の方法ですか? –

答えて

0

1)componentWillMountはまだDOMへのアクセス権を持っていないので、あなたはおそらくcomponentDidMountであなたのデータベース要求を呼び出す必要があります。

2)おそらくcomponentWillUpdateを使用して、有効なデータがフォームから取得されているかどうかを確認したり、特定のケースに基づいてコンポーネントの再レンダリングを停止したりすることができます。

0

FormElementのキーが変更されないIDの場合、親をリロードするときに、その要素をアンマウントして再度マウントしないでください。フィールドに入力するたびにcomponentWillMountメソッドが呼び出されていますか?

入力するたびにFormElementが再度マウントされると、入力した内容も消えてしまいます。

+0

フェアポイント。私はより多くのコードを投稿する必要があるかもしれませんが、基本的にFormElementは親フォーム内のformDataという状態を更新し、フォームはそれを使ってFormElementsの配列を設定します – Wayneio

+0

なぜフォームフィールドの内容が、マウント。値は親の状態によって管理され、子に小道具として渡されます。だから、おそらくすべてのドロップダウン値に対して同じことをしたいと思うでしょう。つまり、formData.idおよびformData.valueと同じように、すべてのドロップダウン値を親の状態に保存します。次に、子のcomponentWillMountメソッドで、親から渡されたドロップダウン値(formData.dropdownValuesなど)を確認します。 formData.dropdownValuesが空であるか更新する必要がある場合にのみapi呼び出しを行います。 – brickingup

0

FormElementsの数は動的ですか?もしそうでなければ、私は親のFormElementsごとに別の状態を持つことをお勧めします。次に、変更された要素をリフレッシュするだけです。

より良い方法は、redux-formを使用してredux-storeのフォーム状態を管理することです。各FormElementはストア内の独自の状態にサブスクライブするので、reducexは変更が必要なものだけをリフレッシュします。

関連する問題