Javascript Reactjs 异步渲染组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27192621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reactjs async rendering of components
提问by tuna
I want to render my component after my ajax request is done.
我想在我的 ajax 请求完成后呈现我的组件。
Below you can see my code
下面你可以看到我的代码
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>)
})
}
});
But i get the error below because i am returning render inside the done method of my ajax request.
但是我收到以下错误,因为我在我的 ajax 请求的 done 方法中返回渲染。
Uncaught Error: Invariant Violation: CategoriesSetup.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
Uncaught Error: Invariant Violation: CategoriesSetup.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
Is there a way to wait for my ajax request to end before start rendering?
有没有办法在开始渲染之前等待我的 ajax 请求结束?
回答by Michelle Tilley
There are two ways to handle this, and which you choose depends on which component should own the data and the loading state.
有两种方法可以处理这个问题,您选择哪种方法取决于哪个组件应该拥有数据和加载状态。
Move the Ajax request into the parent and conditionally render the component:
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>; } });Keep the Ajax request in the component and render something else conditionally while it's loading:
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} />; } });
将 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} />; } });
回答by Roman
The basic example of async rendering of components is below:
组件异步渲染的基本示例如下:
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>);
}
}

