2017-07-31 90 views
0

我看了看似乎有類似問題的其他問題,但沒有一個已接受的答案已解決我的問題。我試圖獲取新的名字並將它們加載到子組件中,當使用新ID更新REDX時。子組件不能獲取新數據當Redux由父組件更新時

當我只用終極版和無state(我寧願),新ID不相處到子組件過去了,名字完全不

或者加載,我一直在使用state嘗試爲子組件中的名稱(正如您可以在下面的註釋文本中看到的那樣)。但是......奇怪的是,每次ID改變時,組件都會根據以前的ID而不是當前的ID加載名稱。

終極版

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) { 

替代A線BOVE

我寧願將數據存儲在redux中,以便其他組件可以訪問數據,但這樣做的確允許數據加載,但是它會加載滯後(即,當我改變的ID,它加載關聯到以前的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); 

替代線以上

我寧願存儲在終極版中的數據,使其對其他組件訪問,但這樣做並允許要加載的數據,但它具有滯後性負載(即當我改變的ID,它加載關聯到以前的ID的名稱)

 // 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的數據?

+0

有點困惑你的父組件。如果你把一個console.log(this.props.user)放在渲染中,你看到了什麼?它看起來像你正在將'reduxData'作爲道具傳遞給你的父組件,但你只是調用'this.props.user',我不確定它如何在不破壞'reduxData'看起來的情況下獲得訪問權限 –

+0

這是一個錯字。我更新了問題中的ParentComponent。現在它應該更有意義 – Rbar

回答

0

可能是因爲對象鍵被改變而沒有對象引用。 一個hacky的解決方案將在更改後致電this.forceUpdate()更新組件:)

0

提示:如果您使用新的JavaScript語法,則不需要綁定您的函數。

this.add = this.add.bind(this);將通過書面方式add方法等來解決:

add =() => { 
}; 
+0

這將返回'語法錯誤:意外的標記' – Rbar

+0

我更新了答案。這應該是正確的。 –

+0

這仍然返回'語法錯誤:意外的標記'(在'add'之後直接指示'=') – Rbar

0

我有我在那裏分量多次加載一個孩子在一個頁面上,儘管傳入了我認爲是一個唯一的ID類似的問題它只會引用第一個ID。我知道這不完全是你有的情況,但這將允許你有一個獨特的對象鍵和一個獨特的對象引用,希望能解決你的問題。

這是我用於此的包:https://www.npmjs.com/package/react-html-id。當你導入包時,你需要有大括號。

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

其餘的解釋在npm上。

0

問題是子組件componentWillReceiveProps。您沒有使用傳播到此組件的新道具。 componentWillReceiveProps與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); 
} 
相關問題