我正在componentDidMount中获取数据并更新状态,并且出现了著名的警告:
无法在已卸载的组件上执行React状态更新。这是 无操作,但表示您的应用程序内存泄漏。修理, 取消所有订阅和异步任务 componentWillUnmount方法。
state = {
post: null
}
render() {
console.log(this.props.postId)
if (this.props.post) {
return (
<div>
<h3> {this.state.post.postTitle} </h3>
<p> {this.state.post.postBody} </p>
</div>
);
} else {
return <Redirect to="/blog" />
}
}
componentDidMount() {
this._isMounted = true;
axios
.get('https://jsonplaceholder.typicode.com/posts/' + + this.props.postId)
.then((response) => {
let post = {
id: response.data.id,
postTitle: response.data.title,
postBody: response.data.body
}
this.setState((prevState,props)=>{
console.log('post',post)
console.log('prevState',prevState)
console.log('props',props)
})
})
.catch((e) => {
console.log('error', e)
})
}
}
是什么导致此警告,以及获取数据和更新状态的最佳方法是什么?
答案 0 :(得分:2)
您的问题与以下question相同。
如何开发组件,您可以进入一个循环并无限执行渲染。为了防止这种情况,请再添加一种状态和控制,以使请求仅发出1次,或者仅在需要时发出“正念”请求。
此外,您的代码需要进行一些更改,您可以使用State验证是否显示某些内容,并在发出请求后再次设置状态。进行一些更改后,您的代码将如下所示:
state = {
loadingData: true,
post: null
}
render() {
if (!this.state.loadingData) {
return (
<div>
<h3> {this.state.post.postTitle} </h3>
<p> {this.state.post.postBody} </p>
</div>
);
} else {
return <Redirect to="/blog" />
}
}
componentDidMount() {
this._isMounted = true;
if(this.state.loadingData)
axios
.get('https://jsonplaceholder.typicode.com/posts/' + + this.props.postId)
.then((response) => {
this.setState({
loadingData: false,
post: {
id: response.data.id,
postTitle: response.data.title,
postBody: response.data.body
}
})
})
.catch((e) => {
console.log('error', e)
})
}
我希望它有用。 问候
答案 1 :(得分:1)
只需创建状态为isMounted: false
的标志即可。在componentDidMount中设置状态isMounted = true
,在componentWillUnmount中,设置状态isMounted = false
。
然后在需要使用setState函数的异步函数中,按条件if(this.state.isMounted) { ....setState action }