2014-11-28 13 views
51

Voglio rendere il mio componente dopo che la richiesta di ajax è stata eseguita.Reactjs rendering async dei componenti

Qui sotto potete vedere il mio codice

var CategoriesSetup = React.createClass({ 

    render: function(){ 
     var rows = []; 
     $.get('http://foobar.io/api/v1/listings/categories/').done(function (data) { 
      $.each(data, function(index, element){ 
       rows.push(<OptionRow obj={element} />); 
      }); 
      return (<Input type='select'>{rows}</Input>) 

     }) 

    } 
}); 

ma ho l'errore sotto perché sto tornando il rendering all'interno del metodo fatto della mia richiesta Ajax.

Uncaught Error: Invariant Violation: CategoriesSetup.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

Esiste un modo per aspettare la mia richiesta ajax per terminare prima del rendering di partenza?

+2

Inoltre, una piccola nitpick ma che ha un recupero di dati in una routine di rendering() non è davvero una grande idea. Mantieni rendering() per renderizzare e astrarre il resto. Inoltre, potresti voler ottenere quei dati solo una volta, non ogni volta che il componente viene reso. –

risposta

90

Ci sono due modi per gestire questo e che si sceglie dipende da quale componente deve possedere i dati e lo stato di caricamento.

  1. Spostare la richiesta Ajax nel genitore e condizionatamente rendere il componente:

    var Parent = React.createClass({ 
        getInitialState: function() { 
        return { data: null }; 
        }, 
    
        componentDidMount: function() { 
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) { 
         this.setState({data: data}); 
        }.bind(this)); 
        }, 
    
        render: function() { 
        if (this.state.data) { 
         return <CategoriesSetup data={this.state.data} />; 
        } 
    
        return <div>Loading...</div>; 
        } 
    }); 
    
  2. Mantenere la richiesta Ajax nel componente e rendere qualcos'altro condizionalmente mentre è carico:

    var CategoriesSetup = React.createClass({ 
        getInitialState: function() { 
        return { data: null }; 
        }, 
    
        componentDidMount: function() { 
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) { 
         this.setState({data: data}); 
        }.bind(this)); 
        }, 
    
        render: function() { 
        if (this.state.data) { 
         return <Input type="select">{this.state.data.map(this.renderRow)}</Input>; 
        } 
    
        return <div>Loading...</div>; 
        }, 
    
        renderRow: function(row) { 
        return <OptionRow obj={row} />; 
        } 
    }); 
    
+4

Mi sono imbattuto in questa risposta nel 2017, queste due migliori soluzioni rimangono ancora le migliori da usare? – Dan

+0

@Dan React esegue il rendering dell'interfaccia utente basata su oggetti di scena e stato, quindi il concetto di base rimarrà lo stesso: esegui la richiesta Ajax, imposta uno stato e ri-rendering qualcosa. Tuttavia, modelli come i componenti di ordine superiore sono diventati più popolari, dimostrando come si possano astrarre le complessità. –

+0

'if (this.state.data)' dovrebbe essere 'if (this.state && this.state.data)' perché a volte lo stato può essere nullo. – Timo

Problemi correlati