admin管理员组

文章数量:1388116

I have a React app with one parent ponent and three child ponents. In parent ponent I have state containing data and pass those data in props to child ponents. I have also three endpoints and have to send three ajax requests on parent ponent's ponentDidMount function. How to do this in React?

var Parent = React.createClass({
    getInitialState: function(){
        return ( {
            data1: [],
            data2: [],
            data3: []
        });
    },
    ponentDidMount: 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>
        )
    }
})

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

Thanks in advance.

I have a React app with one parent ponent and three child ponents. In parent ponent I have state containing data and pass those data in props to child ponents. I have also three endpoints and have to send three ajax requests on parent ponent's ponentDidMount function. How to do this in React?

var Parent = React.createClass({
    getInitialState: function(){
        return ( {
            data1: [],
            data2: [],
            data3: []
        });
    },
    ponentDidMount: 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>
        )
    }
})

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

Thanks in advance.

Share Improve this question edited Aug 10, 2016 at 7:17 Season 4,3762 gold badges18 silver badges23 bronze badges asked Aug 10, 2016 at 6:55 magnatmagnat 4174 silver badges19 bronze badges 5
  • Show as your code.. – Hardy Commented Aug 10, 2016 at 6:57
  • You can use for example this library: caolan.github.io/async – Hardy Commented Aug 10, 2016 at 7:12
  • You can make nested ajax calls. call1.success(call2.success(call3.success(setState))) – vijayst Commented Aug 10, 2016 at 7:28
  • If you are looking for parallelism. successCount = 0; call1.success(successCount++); if (successCount === 3) setState(); – vijayst Commented Aug 10, 2016 at 7:30
  • I'm looking for parallelism but to make this feature effective I would like to do all requests at the same time. – magnat Commented Aug 10, 2016 at 7:36
Add a ment  | 

1 Answer 1

Reset to default 6

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.

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: []
        });
    },
    ponentDidMount: 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>
        )
    }
})

// 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);
    },

    ponentDidMount: function() {
       axios.all(this.props.ajaxApi.map(function(api) {
           fetchApiCallData(api)
       })).then(axios.spread(function(req1, req2, req3) {
        // requests plete
           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>
        )
    }
   })

本文标签: javascriptSeveral requests on componentDidMountStack Overflow