我有一个带有一个父组件和三个子组件的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个请求,更新状态并将数据作为道具传递给子组件,前提是所有3个请求均成功完成,然后渲染/重新渲染这些子组件。如果一个请求有问题,我不想呈现任何子组件(正在加载…一直进行到成功为止)。异步还是前一个请求成功?
提前致谢。
这样的事情可能会起作用。Ajax调用是伪代码。我假设您正在使用一些ajax api库。-在此示例中,我使用超级代理(没有附加的Promise lib,而是使用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> ) } })