tun*_*nak 77 javascript ajax asynchronous jquery-deferred 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>)
})
}
});
Run Code Online (Sandbox Code Playgroud)
但我得到下面的错误,因为我在我的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.
有没有办法在开始渲染之前等待我的ajax请求结束?
Mic*_*ley 123
有两种方法可以处理这个问题,您选择哪种方法取决于哪个组件应该拥有数据和加载状态.
将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>;
}
});
Run Code Online (Sandbox Code Playgroud)将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} />;
}
});
Run Code Online (Sandbox Code Playgroud)组件异步呈现的基本示例如下:
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>);
}
}
Run Code Online (Sandbox Code Playgroud)