为了填充React组件的内容,我在方法componentWillMount的主体中使用AJAX请求,在那里我因执行请求而更改this.state。问题是render方法在请求完成之前运行,就像this.state在setState之后更改一样。此外,如果这样的组件呈现一个,也使用AJAX,则渲染调用的数量增长为2的幂。
如何在获得必要的数据后才能渲染组件?
var News = React.createClass({
getInitialState: function () {
return {
news: [],
page: 1
};
},
componentWillMount: function () {
let xmlhttp = getXmlHttp();
xmlhttp.open("POST", "server/news.php", true);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.onreadystatechange=() => {
if (xmlhttp.readyState != 4) return;
clearTimeout(timeout);
if (xmlhttp.status == 200) {
this.setState({
news: eval(xmlhttp.responseText.toString())
});
} else {
handleError(xmlhttp.statusText);
}
};
xmlhttp.send('page=' + this.state.page);
var timeout = setTimeout( function(){ xmlhttp.abort(); handleError("Request time over") }, 10000);
},
render: function () {
let itemList = this.state.news.map(function(item, iterator){
return (
<NewsItem
niTitle={item[0]}
niText={item[1]}
niDate={item[2]}
niImg={item[3]}
key={"ni " + iterator}
/>
);
});
return (
<div>
{itemList}
<PageChanger page={this.state.page}/>
</div>
);
}
});
答案 0 :(得分:3)
如何在获取组件后才能渲染组件 必要的数据?
如果您的render
函数返回false
,则不会呈现任何内容。
(来源:the docs。)
因此,您可以在初始状态下设置一个标志:
getInitialState: function () {
return { page: 1, shouldRender: false };
}
然后,在render
中,您可以检查该标志:
if (! this.state.shouldRender) return false;
在传递给XHR的回调中,您可以更新标志:
this.setState({
shouldRender: true,
news: eval(xmlhttp.responseText.toString()),
});
答案 1 :(得分:-1)
首先,将您的网络调用抽象为帮助程序,并根据需要导入到组件中。
其次,使用componentDidMount
而不是componentWillMount
来避免多次渲染。
例如:
import networkCall from ../helpers/networkCall
componentDidMount() {
this.setState({
emails: networkCall.news,
emailCache: networkCall.page
});
},