2016-11-20 2 views
2

私は基本的な内容を書いています + Firebaseアプリケーションはどのように動作するかを識別するためのものです。リアクションコンポーネントはfirebase child_updateイベントで再レンダリングされません

IはFirebaseデータベースから返された設定データに基づいて反応する成分(ポスト)のリストを返す反応成分(ViewPosts)を有します。

は私がをchild_removed Firebaseイベントを添付しました、をchild_addedとcomponentDidMount()

に私は正常に動作して取り付けていたすべてのイベントををchild_changedだけイベントが再されていません child_changedページをレンダリングします。イベントがトリガされたかどうかを確認するためにを追加しました。 (私はfirebaseコンソールを使って値を更新/削除しています)

私はキーに問題があると思っていましたので、インデックスを追加してユニークにしましたが、まだ運がありません。なぜコードが私にこのような振る舞いを与えているのですか?

Reactは更新されたコンポーネントのみを更新するので、リストに新しいコンポーネントを追加したり削除したりしてもリストは更新されませんが、1つのコンポーネントが削除され、そのコンポーネントが更新されたコンポーネント(Post) Reactは強制的にそのコンポーネントの下のリストを再レンダリングするので、私は更新された値を見ることができます。

すると、これは

ViewPosts

import React, { Component } from 'react'; 
import * as firebase from 'firebase'; 
import Post from './Post'; 

var listItems = null; 
var starCountRef = null; 
class ViewPosts extends Component { 

    constructor(props) { 
    super(props); 
    this.state = {renderedList: []}; 
    this.getDatafromDB = this.getDatafromDB.bind(this); 
    starCountRef = firebase.database().ref('posts'); 
    } 

    getDatafromDB() { 
    listItems = []; 
    starCountRef.once('value', snapshot => { 
     var results = snapshot.val(); 
     var resultsKeys = Object.keys(results); 
     listItems = resultsKeys.map((key,i) => <Post key={key.toString() + i} value={results[key].value + i } />); 

     this.setState({ 
     renderedList : listItems 
     }); 
    }); 
    } 
    componentDidMount(){ 

    // Get the data on a post that has been removed 
    starCountRef.on("child_removed", snapshot => { 
     var deletedPost = snapshot.val(); 
     console.log("The post valued '" + deletedPost.value + "' has been deleted"); 
     this.getDatafromDB(); 
    }); 

    // Get the data on a post that has been removed 
    starCountRef.on("child_added", snapshot => { 
     var addedPost = snapshot.val(); 
     console.log("The post value '" + addedPost.value + "' has been added"); 
     this.getDatafromDB(); 
    }); 

    starCountRef.on("child_changed", snapshot => { 
     var changedPost = snapshot.val(); 
     console.log("The updated post value is " + changedPost.value); 
     this.getDatafromDB(); 
     console.log("this.state.listItems " + this.state.renderedList); 
    }); 

    } 
    render() { 
    return(
    <div> 
     <ul> 
     {this.state.renderedList} 
     </ul> 
     </div> 
    ); 
} 
} 

export default ViewPosts; 

が起こっている理由をお知らせ

import React, { Component } from 'react'; 

class Post extends Component { 

    constructor(props) { 
    super(props); 
    this.state = {value: props.value}; 
    } 

render() { 
    return(
    <li>{this.state.value}</li> 
    ); 
} 
} 

export default Post; 

答えて

0
を識別するために私を助けてください

私は、新しいプロパティ "UID" を導入し、UIDそれにマッピングされましたコンポーネントのキー その後、UIDと値の両方を更新すると、Reactがそのコンポーネントを更新として選択し、そのコンポーネントを再描画しました。

キーの上に1つのコンポーネントを削除するまでキーにインデックスを含めても、キーが同じになり、コンポーネントを上から削除したときに再レンダリングされる理由が説明されます。

基本的に同じタイプのコンポーネントが複数ある場合、一意のキーで結ばれていなければなりません。キーが変更されない限り、Reactは値が変更されてもコンポーネントを再描画しません。

React doがバックグラウンドであることを知っている限り、仮想DOMを作成してそれを既存のものと比較し、変更されたコンポーネントのみを再レンダリングします。そして、やったときにそれが複数がある場合、キーを探し、その同じ場合は、私はlodashの_.uniqueId([prefix=''])方法

を使用して1を生成した鍵を作成したか疑問ならば、それは場合にも、全コンポーネントに

をスキップするように思えますありがとう、

関連する問題