Асинхронный рендеринг компонентов Reactjs
Я хочу отобразить мой компонент после того, как мой запрос 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-запрос, чтобы закончить, прежде чем начать рендеринг?
2 ответа:
есть два способа справиться с этим, и какой вы выберете зависит от того, какой компонент должен владеть данными и загрузки.
переместите запрос 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} />; } });
основной пример асинхронного рендеринга компонентов приведен ниже:
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>); } }