子组件不能获取新数据当Redux由父组件更新时
我看了看似乎有类似问题的其他问题,但没有一个已接受的答案已解决我的问题。我试图获取新的名字并将它们加载到子组件中,当使用新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);
类似的问题:
- https://github.com/gaearon/redux-thunk/issues/80
- React Native Child Component Not Updated when redux state changes
- update child component when parent component changes
有谁知道我怎样才能让我的组件来加载基于在终极版当前ID的数据?
可能是因为对象键被改变而没有对象引用。 一个hacky的解决方案将在更改后致电this.forceUpdate()
更新组件:)
我有我在那里分量多次加载一个孩子在一个页面上,尽管传入了我认为是一个唯一的ID类似的问题它只会引用第一个ID。我知道这不完全是你有的情况,但这将允许你有一个独特的对象键和一个独特的对象引用,希望能解决你的问题。
这是我用于此的包:https://www.npmjs.com/package/react-html-id。当你导入包时,你需要有大括号。
import { enableUniqueIds } from 'react-html-id'
其余的解释在npm上。
问题是子组件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);
}
有点困惑你的父组件。如果你把一个console.log(this.props.user)放在渲染中,你看到了什么?它看起来像你正在将'reduxData'作为道具传递给你的父组件,但你只是调用'this.props.user',我不确定它如何在不破坏'reduxData'看起来的情况下获得访问权限 –
这是一个错字。我更新了问题中的ParentComponent。现在它应该更有意义 – Rbar