对componentDidMount的几个请求 [英] Several requests on componentDidMount

查看:88
本文介绍了对componentDidMount的几个请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有一个父组件和三个子组件的React应用程序。在父组件中,我有包含数据的状态,并将这些数据传递给子组件。我还有三个端点,必须在父组件的componentDidMount函数上发送三个ajax请求。如何在React中执行此操作?

I have a React app with one parent component and three child components. In parent component I have state containing data and pass those data in props to child components. I have also three endpoints and have to send three ajax requests on parent component's componentDidMount function. How to do this in 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个请求都成功完成,然后呈现/重新呈现这些子组件时才转到子组件。如果一个请求出现问题,我不想渲染任何子组件(正在加载......一直持续到成功)。异步或前一个成功的一个请求?

I want to render parent component with overlay "Loading ..." and on componentDidMount send 3 requests, update state and pass data as a props to child components only if all 3 requests are finished with success and then render / rerender these child components. If there is a problem with one request I don't want to render any child component (Loading... is keep going until success). Async or one request in success of previous one?

提前致谢。

推荐答案

这样的事情可行。 ajax调用是伪代码。我假设你正在使用一些ajax api libarary。 - 在这个例子中,我使用superagent(没有额外的承诺lib,而只是使用es6承诺)。
我使用Promise.all的地图 - 基本上,我们等到所有ajax请求都返回..在then中我用结果更新状态。一旦promise.all得到解决,它就会按照您发出请求的顺序传递包含每个请求的数组。在ajaxApi中 - 这些是api调用。我希望这有帮助。

Something like this could work. The ajax calls are psuedo-code. I assume you are using some ajax api libarary. - in this example, I use superagent (w/o its additional promise lib, instead I just use the es6 promise). I use map with Promise.all - basically, we wait till all ajax requests get returned.. in the "then" I update the state with the results. Once the promise.all is resolve, it passes on an array containing each of the requests, in the order you make the request. In "ajaxApi" - those are the api calls. I hope this helps.

注意:我在这里假设es6,因此我使用了promise.all和一些es6 shorthan。如果你不使用es6,我道歉。让我知道,我可以展示非es6解决方案。

NOTE: I am assuming es6 here, thus my usage of promise.all and some es6 shorthan. If you are not using es6, I apologize. Let me know, and I can show a non es6 solution.

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版本。我在这里做一些假设。我希望你能适应自己的需要。

// here is an Axios version w/o es6. I am making some assumptions here. I hope you can adapt to your own needs.

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

这篇关于对componentDidMount的几个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆