2016-08-10 25 views
4

Ich habe eine React App mit einer Elternkomponente und drei untergeordneten Komponenten. In der Elternkomponente habe ich einen Zustand, der Daten enthält, und gebe diese Daten in Requisiten an untergeordnete Komponenten weiter. Ich habe auch drei Endpunkte und muss drei Ajax-Anfragen an die ComponentDidMount-Funktion der Elternkomponente senden. Wie macht man das in React?Mehrere Anfragen auf componentDidMount

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

Ich mag übergeordnete Komponente mit Overlay machen „Loading ...“ und auf componentDidMount 3 Anfragen senden, Zustand aktualisieren und nur Daten als Requisiten Kind Komponenten passieren, wenn alle drei Anforderungen mit Erfolg abgeschlossen werden und dann render/render diese Kindkomponenten. Wenn es ein Problem mit einer Anforderung gibt, möchte ich keine untergeordnete Komponente rendern (Laden ... wird bis zum Erfolg fortgesetzt). Async oder eine Anfrage zum Erfolg des vorherigen?

Vielen Dank im Voraus.

+0

zeigen, wie Sie Ihren Code .. – Hardy

+0

-Code geliefert :) – magnat

+0

Sie zum Beispiel diese Bibliothek verwenden können: http://caolan.github.io/async/ – Hardy

Antwort

6

So etwas könnte funktionieren. Die Ajax-Aufrufe sind Pseudo-Code. Ich nehme an, dass Sie eine Ajax API Bibliothek verwenden. - In diesem Beispiel verwende ich superagent (ohne seine zusätzliche Promise-Lib, stattdessen verwende ich einfach das es6-Versprechen). Ich benutze Karte mit Promise.all - im Grunde warten wir, bis alle Ajax-Anfragen zurückgegeben werden .. im "dann" aktualisiere ich den Zustand mit den Ergebnissen. Sobald die provect.all-Lösung aufgelöst wurde, wird ein Array mit allen Anforderungen in der Reihenfolge übergeben, in der Sie die Anforderung gestellt haben. In "ajaxApi" - das sind die api-Anrufe. Ich hoffe das hilft.

HINWEIS: Ich nehme es6 hier, also meine Verwendung von Promise.all und einige es6 shorthan. Wenn Sie ES6 nicht verwenden, entschuldige ich mich. Lass es mich wissen, und ich kann eine non es6 Lösung zeigen.

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

// hier ist eine Axios Version ohne es6. Ich mache hier einige Annahmen. Ich hoffe, dass Sie sich an Ihre eigenen Bedürfnisse anpassen können.

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

Wow, es löscht meinen Kopf :) Können Sie es5 Lösung zeigen? Es6 für mich noch in Arbeit. Danke vielmals. Ich benutze Axios als Ajax Api – magnat

+0

ok, ich habe eine Axios-Version hinzugefügt. Ich hoffe, es hilft. Es wird nicht getestet, aber ich denke, das sollte dich auf den richtigen Weg bringen. –

+1

Erstaunlich, vielen Dank noch einmal. Es klappt... – magnat