Я хочу отобразить свой компонент после того, как мой запрос ajax будет выполнен.
Ниже вы можете увидеть мой код
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>)
})
}
});
Но я получаю сообщение об ошибке ниже, потому что я возвращаю рендеринг внутри метода done моего запроса 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.
Есть ли способ дождаться завершения моего запроса ajax перед началом рендеринга?
Ответы:
Есть два способа справиться с этим, и выбор зависит от того, какой компонент должен владеть данными и от состояния загрузки.
Переместите запрос 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>; } });
Сохраните запрос 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} />; } });
источник
if (this.state.data)
должно быть,if (this.state && this.state.data)
потому что иногда состояние может быть нулевым.this.state
быnull
?Базовый пример асинхронного рендеринга компонентов ниже:
import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; export default class YourComponent extends React.PureComponent { constructor(props){ super(props); this.state = { data: null } } componentDidMount(){ const data = { optPost: 'userToStat01', message: 'We make a research of fetch' }; const endpoint = 'http://example.com/api/phpGetPost.php'; const setState = this.setState.bind(this); fetch(endpoint, { method: 'POST', body: JSON.stringify(data) }) .then((resp) => resp.json()) .then(function(response) { setState({data: response.message}); }); } render(){ return (<div> {this.state.data === null ? <div>Loading</div> : <div>{this.state.data}</div> } </div>); } }
источник