我有一个父组件执行 AJAX 调用以获取 JSON 对象。我已经做了一些 console.log 以确保数据在父组件中是正确的,但是当我通过 props 时,我得到一个值:
ƒ data() {
return _this.state.data;
}
到目前为止我所做的似乎很简单,所以我找不到问题所在。
父组件:
class InfoBox extends Component {
state = {
data: []
};
componentDidMount = () => {
this.loadDonationsFromServer();
setInterval(this.loadDonationsFromServer, this.props.pollInterval);
};
loadDonationsFromServer = () => {
$.ajax({
url: "https://jsonplaceholder.typicode.com/comments",
dataType: "json",
cache: false,
success: data => {
this.setState({ data });
},
error: (xhr, status, err) => {
console.error(status, err.toString());
}
});
};
render = () => {
return (
<React.Fragment>
<h1>Information</h1>
<InfoList
data={() => this.state.data}
/>
</React.Fragment>
);
};
}
export default DonationBox;
子组件:
class InfoList extends Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data
};
}
componentDidMount() {
console.log(this.state.data);
//logs: ƒ data() {
// return _this.state.data;
// }
}
render() {
return <div> Placeholder </div>;
}
}
export default InfoList;
我尝试在子组件中使用 bind 但仍然得到同样的结果:
constructor(props) {
super(props);
this.state = {
data: this.props.data
};
this.checkData = this.checkData.bind(this);
}
componentDidMount() {
this.checkData();
}
checkData = () => {
console.log(this.state.data);
};
最佳答案
首先,是,您应该更改 data
您发送至 InfoList
的 Prop 成为this.state.data
而不是匿名函数。所以:<InfoList data={this.state.data} />
但是,主要问题在于使用 componentDidMount
在子组件中,当真的你应该使用componentWillReceiveProps
相反。
componentDidMount 只被调用一次,它不会等待你的 AJAX
componentDidMount
生命周期 Hook 在初始 render
之前被调用一次.
在您的子组件中,位于 componentDidMount
您正在尝试记录 this.state.data
- 但此状态基于构造函数中设置的内容,即作为 data
传入的内容首次安装时的 Prop InfoList
.那是 []
,因为 InfoBox
尚未收到来自其 Ajax 调用的返回数据。换句话说:
InfoList.componentDidMount()
fired beforeInfoBox.loadDonationsFromServer()
got back its response. AndInfoList.componentDidMount()
does not get fired again.
componentWillReceiveProps 在 props 改变时被调用
相反,您的子组件应该使用 componentWillReceiveProps
生命周期钩子(Hook)。每次组件接收到新 Prop 时都会调用它。一旦 parent 的状态发生变化(负载捐赠返回后),它就会将新的 Prop 传递给 child 。在 componentWillReceiveProps
, child 可以拿走这些新 Prop 并更新他的状态。
我创建了一个 code sandbox它通过一堆日志语句向您展示什么时候发生了什么,以及您的 props 和 state 在生命周期的各个点上是什么样子的。我没有实际执行 ajax 获取,而是等待 2 秒来模拟获取。在 InfoList.js
, componentWillReceiveProps
的代码目前已被注释掉;通过这种方式,您可以看到事情是如何运作的。删除评论并开始使用 componentWillReceiveProps
后,您会看到它们是如何修复的。
其他资源
这是一个 helpful article这几乎描述了您面临的完全相同的问题。
关于 React 生命周期钩子(Hook)的优秀快速引用是 React Cheat Sheet )
关于javascript - 为什么我得到的是 "return _this.state.data"而不是 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54896750/