我有一个包含一个父组件和三个子组件的 React 应用程序。在父组件中,我有包含数据的状态,并将 props 中的这些数据传递给子组件。我还有三个端点,必须在父组件的 componentDidMount 函数上发送三个 ajax 请求。如何在 React 中执行此操作?
var Parent = React.createClass({
getInitialState: function(){
return ( {
data1: [],
data2: [],
data3: []
});
},
componentDidMount: function() {
???
???
???
},
render: function(){
return (
<div>
<Child1 data={this.state.data1} />
<Child2 data={this.state.data2} />
<Child3 data={this.state.data3} />
</div>
)
}
})
var Child1 = React.createClass({
render: function() {
return (
<div>
{this.props.data}
</div>
)
}
})
var Child2 = React.createClass({
render: function() {
return (
<div>
{this.props.data}
</div>
)
}
})
var Child3 = React.createClass({
render: function() {
return (
<div>
{this.props.data}
</div>
)
}
})
我想渲染带有叠加层“Loading ...”的父组件,并在 componentDidMount 上发送 3 个请求,更新状态并将数据作为 props 传递给子组件,只有当所有 3 个请求都成功完成,然后渲染/重新渲染这些子组件。如果一个请求有问题,我不想渲染任何子组件(加载...一直持续到成功)。异步还是前一个请求成功?
提前致谢。
最佳答案
像这样的东西可以工作。 ajax 调用是伪代码。我假设您正在使用一些 ajax api 库。 - 在这个例子中,我使用 superagent(没有它的附加 promise 库,而是我只使用 es6 promise )。 我将 map 与 Promise.all 一起使用 - 基本上,我们等到所有 ajax 请求都返回.. 在“然后”我用结果更新状态。一旦 promise.all 被解析,它就会按照您发出请求的顺序传递一个包含每个请求的数组。在“ajaxApi”中——那些是 api 调用。我希望这有帮助。
注意:我在这里假设 es6,因此我使用了 promise.all 和一些 es6 shorthan。如果您不使用 es6,我深表歉意。让我知道,我可以展示一个非 es6 解决方案。
var Parent = React.createClass({
getDefaultProps: function() {
return {
ajaxApi: ['foo1','foo2','foo3']
};
},
getInitialState: function(){
return ( {
data1: [],
data2: [],
data3: []
});
},
componentDidMount: function() {
Promise.all(this.props.ajaxApi
.map(a => {
return new Promise((resolve, reject) => {
//using superagent here (w/o its promise api), "import request as 'superagent'. You'd import this at the top of your file.
request.get(a)
.end((error, response) => {
if (error) {
return resolve(response)
} else {
resolve()
}
})
})
)
.then(v => {
this.setState({
data1: v[0],
data2: v[1],
data3: v[2]
})
})
.catch(() => {
console.error("Error in data retrieval")
})
},
render: function(){
return (
<div>
<Child1 data={this.state.data1} />
<Child2 data={this.state.data2} />
<Child3 data={this.state.data3} />
</div>
)
}
})
//这是一个没有 es6 的 Axios 版本。我在这里做一些假设。希望大家能适应自己的需求。
var Parent = React.createClass({
// these are your api calls
getDefaultProps: function() {
return {
ajaxApi: ['api/call/1','api/call/2','api/call/3']
};
},
getInitialState: function(){
return ( {
data1: [],
data2: [],
data3: []
});
},
fetchApiCallData: function(api) {
return axios.get(api);
},
componentDidMount: function() {
axios.all(this.props.ajaxApi.map(function(api) {
fetchApiCallData(api)
})).then(axios.spread(function(req1, req2, req3) {
// requests complete
this.setState({
data1: req1,
data2: req2,
data3: req3
})
}));
},
render: function(){
return (
<div>
<Child1 data={this.state.data1} />
<Child2 data={this.state.data2} />
<Child3 data={this.state.data3} />
</div>
)
}
})
关于javascript - componentDidMount 上的几个请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38866262/