2014-11-28 4 views
51

Я хочу отобразить мой компонент после выполнения моего запроса ajax.Reactjs async рендеринг компонентов

Ниже вы можете видеть, что мой код

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

     }) 

    } 
}); 

Но я получаю ошибку ниже, потому что я возвращаю визуализации внутри делается методом моего 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.

Есть ли способ ждать мой Аякса запрос закончить перед запуском рендеринга?

+2

Кроме того, небольшая nitpick, но имеющая извлечение данных в процедуре render(), на самом деле не отличная идея. Держите render() для рендеринга и абстрагирования остальных. Кроме того, вы можете получать данные только один раз, а не каждый раз, когда компонент отображается. –

ответ

90

Есть два способа справиться с этим, и вы выбираете, зависит от того, какой компонент должен владеть данными и состоянием загрузки.

  1. Перемещение запроса Ajax в родителя и условно делают компонент:

    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. Держите запрос Ajax в компоненте и сделать что-то другое условно, а это нагрузка:

    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

Я наткнулся на этот ответ в 2017 году, эти два лучших решения по-прежнему остаются лучшими в использовании? – Dan

+0

@Dan React отображает пользовательский интерфейс на основе реквизита и состояния, поэтому основная концепция останется прежней - выполните запрос Ajax, установите какое-то состояние и повторите визуализацию. Однако модели, подобные компонентам более высокого порядка, стали более популярными, демонстрируя, как можно абстрагироваться от сложностей. –

+0

'if (this.state.data)' должно быть 'if (this.state && this.state.data)', потому что иногда состояние может быть нулевым. – Timo