在我的react组件中,当ajax请求正在进行时,im尝试实现一个简单的微调器- im使用state来存储加载状态。
出于某种原因,我的React组件中的下面这段代码抛出了这个错误
只能更新已挂载或正在挂载的组件。这通常意味着您在未挂载的组件上调用setState()。这是个禁区。请检查未定义组件的代码。
如果我去掉了第一个setState调用,错误就会消失。
constructor(props) {
super(props);
this.loadSearches = this.loadSearches.bind(this);
this.state = {
loading: false
}
}
loadSearches() {
this.setState({
loading: true,
searches: []
});
console.log('Loading Searches..');
$.ajax({
url: this.props.source + '?projectId=' + this.props.projectId,
dataType: 'json',
crossDomain: true,
success: function(data) {
this.setState({
loading: false
});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
this.setState({
loading: false
});
}.bind(this)
});
}
componentDidMount() {
setInterval(this.loadSearches, this.props.pollInterval);
}
render() {
let searches = this.state.searches || [];
return (<div>
<Table striped bordered condensed hover>
<thead>
<tr>
<th>Name</th>
<th>Submit Date</th>
<th>Dataset & Datatype</th>
<th>Results</th>
<th>Last Downloaded</th>
</tr>
</thead>
{
searches.map(function(search) {
let createdDate = moment(search.createdDate, 'X').format("YYYY-MM-DD");
let downloadedDate = moment(search.downloadedDate, 'X').format("YYYY-MM-DD");
let records = 0;
let status = search.status ? search.status.toLowerCase() : ''
return (
<tbody key={search.id}>
<tr>
<td>{search.name}</td>
<td>{createdDate}</td>
<td>{search.dataset}</td>
<td>{records}</td>
<td>{downloadedDate}</td>
</tr>
</tbody>
);
}
</Table >
</div>
);
}
问题是,当组件应该已经被挂载(因为它是从componentDidMount调用的)时,我为什么会收到这个错误?我认为组件挂载后设置状态是安全的?
发布于 2015-10-02 17:38:16
看不到渲染函数有点难。虽然已经可以发现您应该做的事情,但每次您使用间隔时,您必须在卸载时清除它。所以:
componentDidMount() {
this.loadInterval = setInterval(this.loadSearches, this.props.pollInterval);
}
componentWillUnmount () {
this.loadInterval && clearInterval(this.loadInterval);
this.loadInterval = false;
}
由于这些成功和错误回调在卸载后仍可能被调用,因此可以使用interval变量来检查它是否已被挂载。
this.loadInterval && this.setState({
loading: false
});
希望这会有所帮助,如果这不能完成工作,请提供渲染函数。
干杯
发布于 2016-06-01 20:17:05
问题是,当组件应该已经被挂载(因为它是从componentDidMount调用的)时,为什么我会得到这个错误?我认为一旦组件被挂载,设置状态是安全的?
它不是从componentDidMount
调用的。您的componentDidMount
会产生一个回调函数,该函数将在计时器处理程序的堆栈中执行,而不是在componentDidMount
堆栈中执行。显然,当您的回调(this.loadSearches
)执行时,组件已经卸载。
所以被接受的答案将会保护你。如果您使用的其他异步API不允许您取消异步函数(已提交给某个处理程序),则可以执行以下操作:
if (this.isMounted())
this.setState(...
这将消除您在所有情况下报告的错误消息,尽管它确实感觉像是在地毯下清理东西,特别是如果您的API提供了取消功能(就像setInterval
对clearInterval
所做的那样)。
发布于 2017-02-11 23:49:17
对于需要另一种选择的人,ref属性的回调方法是一种变通方法。handleRef的参数是对div DOM元素的引用。
有关refs和DOM的详细信息,请访问:https://facebook.github.io/react/docs/refs-and-the-dom.html
handleRef = (divElement) => {
if(divElement){
//set state here
}
}
render(){
return (
<div ref={this.handleRef}>
</div>
)
}
https://stackoverflow.com/questions/32903001
复制相似问题