2017-07-31 12 views
0

同様の問題を抱えていると思われる他の質問も見ましたが、受け入れられた回答のどれもが私の問題を解決しませんでした。私は新しい名前を取得し、新しいIDでreduxが更新されたときにそれらを子コンポーネントにロードしようとしています。子コンポーネントがReduxを親コンポーネントで更新したときに新しいデータを取得しない

私はReduxの使用なしstate(私が好むように)、新しいIDは、子コンポーネントに渡されませんし、名前はまた、すべての

でロードされません、私はstateを使用して試してみました子コンポーネントの名前については(コメントされているテキストの下に表示されています)。しかし、奇妙なことに、IDが変更されるたびに、コンポーネントは現在のIDではなく、以前のIDに基づいて名前をロードします。 LINE A TO

Reduxの

const initialState = { 
    objectOfIds: {"someID":"someID", "aDifferentID":"aDifferentID"}, // I know this format may seem redundant and odd, but I have to keep it this way 
    arrayOfNames: ["John Doe", "Jenny Smith"] 
} 

親Compoenent

// React 
import React from 'react'; 
import firebase from 'firebase'; 

// Components 
import ListOfNames from './ListOfNames'; 

// Redux 
import {connect} from 'react-redux'; 
import {bindActionCreators} from 'redux'; 
import {set} from './../actions/index.js'; 

class ParentComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    this.changeIDs = this.changeIDs.bind(this); 
    } 

    changeIDs() { 
    this.props.set("objectOfIds",{"aNewID":"aNewID","someOtherID":"someOtherID","anotherID":"anotherID"}); 
    } 

    render (
    return (
     <div> 
     <h2>Parent Component</h2> 
     <button onClick={this.changeIDs}>Change Data</button> 
     <ListOfNames objectOfIds={this.props.reduxData.objectOfIds}/> 
     </div> 
    ) 

) 
} 

function mapStateToProps(state) { 
    return { 
     reduxData: state.reduxData 
    }; 
} 

function matchDispatchToProps(dispatch) { 
    return bindActionCreators({ 
     set: set 
    }, dispatch) 
} 

export default connect(mapStateToProps, matchDispatchToProps)(ParentComponent); 

子供Compoenent

// React 
import React from 'react'; 
import firebase from 'firebase'; 

// Redux 
import {connect} from 'react-redux'; 
import {bindActionCreators} from 'redux'; 
import {set} from './../actions/index.js'; 

// Firebase Database 
var databaseRef; 

class ListOfNames extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state= { 
     arrayOfNames: [] 
    } 
    this.fetchNamesForIds = this.fetchNamesForIds.bind(this); 
    this.add = this.add.bind(this); 
    } 

    componentDidMount() { 
    console.log("componentDidMount triggering..."); 
    firebase.auth().onAuthStateChanged(function (user) { 
     if (!user) { 
     console.log("no user authenticated"); 
     } 
     databaseRef = firebase.database().ref('/people/' + user.uid); 
     this.fetchNamesForIds(this.props.reduxData.objectOfIds); 
    }) 
    } 

    // I have tried making the fetch in componentWillReceiveProps so that the function would run anytime the IDs were updated in redux, but "this.props.objectOfIds" and "this.props.reduxData.objectOfIds" 
    componentWillReceiveProps() { 
    console.log("componentWillReceiveProps triggering..."); 
    console.log("this.props.objectOfIds"); 
    console.log(this.props.objectOfIds); 
    console.log("this.props.reduxData.objectOfIds"); 
    console.log(this.props.reduxData.objectOfIds); 
    this.fetchNamesForIds(this.props.reduxData.objectOfIds); 
    // Note: I have also tried: this.fetchNamesForIds(this.props.objectOfIds); so that the data is passed in from the parent 
    } 

    // fetched the names for the associated IDs 
    fetchNamesForIds(personIds) { 
    if (personIds === [] || personIds === undefined || personIds === null) { 

代替BOVE

他のコンポーネントからアクセスできるようにデータをreduxに格納することをお勧めしますが、これを実行するとデータが読み込まれるようになりましたが、遅延私はIDを変更した場合、それは私はそれが他のコンポーネントにアクセスできるようにReduxの中のデータを保存することを好むだろう

上の行への以前のIDに関連付けられた名前)

 // this.setState({ 
     // arrayOfNames: [] 
     // }); 
     this.props.set("arrayOfNames", []); 
     return 
    } 
    var arrayOfNames = []; 
    // loop through person and set each value into the arrayOfNames array 
    Object.keys(IDs).map(function(person, index) { 
     console.log("person = " + person); 
     console.log("index = " + index); 
     // get names associated with the ids obtained 
     var name = '' 
     databaseRef.child('people').child(person).limitToFirst(1).on("value", function(snapshot) { 
     var firstName = snapshot.child('firstName').val() 
     var lastName = snapshot.child('firstName').val() 
     name = firstName + " " + lastName 
     console.log("name = " + name); 
     arrayOfNames.push(name); 
     console.log("arrayOfNames = " + arrayOfNames); 
     this.props.set("arrayOfNames", arrayOfNames); 

ALTERNATIVEをロードしますが、

012:

 // this.setState({ 
     // arrayOfNames: arrayOfNames 
     // }); 
     }.bind(this)); 
    }.bind(this)); 
    } 

    render() { 
    return(
     (this.props.user.arrayOfNames === [] || this.props.user.arrayOfNames === undefined || this.props.user.arrayOfNames === null || this.props.user.arrayOfNames.length < 1) 
     ? <span>no people selected</span> 
     : <div> 
      <h5>List of People</h5> 
      {this.props.user.arrayOfNames.map((name, index) => { 
       return (
        <h5>{name}</h5> 
      ) 
      })} 
      </div> 
    ) 
    } 
} 

ListOfNames.propsTypes = { 
    objectOfIds: React.PropTypes.Object 
}; 


function mapStateToProps(state) { 
    return { 
     reduxData: state.reduxData 
    }; 
} 

function matchDispatchToProps(dispatch) { 
    return bindActionCreators({ 
     set: set 
    }, dispatch) 
} 

export default connect(mapStateToProps, matchDispatchToProps)(ListOfNames); 

同様の質問(私はIDを変更した場合、すなわち、それは前のIDに関連付けられた名前をロード)のデータをロードすることができますが、それは遅れてロードし、このなかったこと

誰もが、私は私のコンポーネントはReduxの中に現在のIDに基づいてデータをロードするために得ることができる方法を理解していますか?

+0

あなたの子コンポーネントで少し混乱し、これを使用してください。あなたがrender.log(this.props.user)をレンダリングに置くと、何が見えますか? 'reduxData'を親コンポーネントに渡しているようですが、' this.props.user'を呼び出すだけです。どのように 'reduxData'のように見えるかを決めることなく、どのようにアクセスできるのか分かりません –

+0

それは質問のタイプミスでした。私は質問のParentComponentを更新しました。 – Rbar

答えて

0

おそらくオブジェクトキーが変更されていてオブジェクト参照が変更されていないためです。 this.forceUpdate()を呼び出すと、変更後のコンポーネントが更新されます:)

0

ヒント:新しいjavascript構文を使用する場合、関数をバインドする必要はありません。私は1つのページに子供にコンポーネントを複数回ロードされた同様の問題があったと私はユニークなIDだと思ったものの中に渡したにもかかわらず

add =() => { 
}; 
+0

これは '構文エラー:予期しないトークン'を返す – Rbar

+0

答えを更新しました。それは正しいものでなければなりません。 –

+0

これはまだ '構文エラー:予期しないトークン'を返します( 'add'の直後に '='を表示します) – Rbar

0

this.add = this.add.bind(this);は次のようにaddメソッドを足すことによって解決されます最初のIDのみを参照します。私はこれがまさにあなたが持っている状況ではないことを知っていますが、これはあなたが一意のオブジェクトキーとあなたの問題をうまく修正する一意のオブジェクト参照を持つことができます。

これは私がこれに使用したパッケージです:https://www.npmjs.com/package/react-html-id。パッケージをインポートするときは、中括弧が必要です。

import { enableUniqueIds } from 'react-html-id' 

残りはnpmで説明されています。

0

問題は、子コンポーネントのコンポーネントです.WillReceivePropsです。このコンポーネントに伝播される新しい小道具を使用していません。 componentWillReceivePropsは、更新されたpropsを含むnextPropsで呼び出されます。

は、あなたの親コンポーネントによって

componentWillReceiveProps(nextProps) { 
    console.log("componentWillReceiveProps triggering..."); 
    console.log("nextProps.objectOfIds ", nextProps.objectOfIds); 
    console.log("nextProps.reduxData.objectOfIds ", nextProps.reduxData.objectOfIds); 
    this.fetchNamesForIds(nextProps.reduxData.objectOfIds); 
} 
関連する問題