2016-08-04 4 views
0

Reactにデータベースの更新と削除がAjax経由で処理される単純なデータベースがあります。Reactで更新後に再レンダリングできません

レコードコンポーネントのAjax呼び出しが成功すると、更新または削除されたレコードがレコードコンポーネントに渡され、すべてのレコードが表示されます。

以下のハンドルメソッドは、レコードの状態を更新し、結果を再レンダリングします。

私の問題は、handleDeleteメソッドがうまくいき、削除されたレコードを使わずにレコードを再描画するのに対し、handleUpdateメソッドはページを更新するまで未更新のレコードを残さないということです。

なぜ、handleUpdateのsetStateが結果を再レンダリングしないのでしょうか?以下は

はコードです:

class Sites extends React.Component { 
    constructor (props) { 
    super(props); 
    this.handleUpdate = this.handleUpdate.bind(this); 
    this.handleDelete = this.handleDelete.bind(this); 
    this.state = {records: this.props.records}; 
    } 
    handleUpdate (record) { 
    let records = this.state.records; 
    let index = records.map((x) => {return x.id}).indexOf(record.id); 
    records.splice(index, 1, record); 
    this.setState({records: records}); # this doesn't re-render the results 
    } 
    handleDelete (record) { 
    let records = this.state.records; 
    let index = records.map((x) => {return x.id}).indexOf(record.id); 
    records.splice(index, 1); 
    this.setState({records: records}); # this re-renders the results 
    } 
    render() { 
    let records = this.state.records.map((record) => { 
     return (
      <Record record={record} key={record.id} handleUpdateRecord={this.handleUpdate} handleDeleteRecord={this.handleDelete}/> 
     ); 
    }); 
    return (
     <div className="col-sm-9"> 
      <table className="table table-striped"> 
      <thead> 
       <tr> 
       <th>Name</th> 
       <th>City</th> 
       <th>State</th> 
       <th>Actions</th> 
       </tr> 
      </thead> 
      <tbody> 
       {records} 
      </tbody> 
      </table> 
     </div> 
    ); 
    } 
    } 
+0

」実装を提供できますか? –

+0

あなたは 'splice'によって状態を変更するべきではありません。 'let records = this.state.records.slice();'を追加する必要があります。 handleUpdateをログに記録しましたか? –

答えて

2

あなたは常に不変ような状態を扱い、決して、これまでそれを直接変更する必要があります。その内容をコピーし、コピーを変更してもう一度設定してください。

私はどちらかのマッピングによって新しいrecords配列を作成したり、古いものをフィルタリングし、それを再度設定し、不変のような状態の治療、私はあなたの<Record />の実装を即興とonUpdateonDeleteロジックを書き換えているペンを用意しました。それを参照してくださいhere。私はいくつかの名前を変更しましたが、ほとんど同じです!

これらは重要なビットです:

handleUpdate (record) { 
    const records = this.state.records.map(r => { 
     if (r.id !== record.id) return r; 
     return record; 
    }) 

    this.setState({records}) 
} 

私たちは、更新されたレコードを受信して​​、古い配列をマップ:我々は新しいものと同じidを持つ要素を見つけた場合、我々は後者を返し、そうでなければ、我々は返します元の要素。 mapは新しい配列を返すので安全です。

handleDelete (id) { 
    const records = this.state.records.filter(r => r.id !== id) 

    this.setState({records}) 
} 

ここでは単にIDを必要とし、我々は削除するidを持つ要素を除外し、状態にrecords配列をフィルタリングします。再び、filterは新しい配列を返します。

希望すると便利です。

+1

これは非常に役に立ちました!私は完全に時間を割いて助けていただきありがとうございます! –

+0

これは非常に奇妙ですが、setState呼び出し後に再レンダリングするようにアップデートを取得するのにはまだ問題があります。以下のコードを追加します。なぜこれがうまくいかないのでしょうか? –

+0

'handleUpdate(site){ constサイト= this.state.sites.map(s => {if(s.id!== site.id)リターンs;リターンサイト;}); this.setState({sites}); コンソール。ログ(サイト); } ' –

0

小道具を受信すると、更新された状態を使用する簡単な

componentWillReceiveProps() {} 

火災。

関連する問題