我遇到了一个大型 React 应用程序出现经典错误的问题:
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
我知道主要原因是在仍然发生查询时卸载组件,并且解决方案是使用 AbortController。
我们使用的是graphQL Apollo,但不是useQuery
钩子。所以我们有一个类似的方法:
getCoreCollections = async () => {
const result = await this.state.api.gql.query({
query: <hidden query method>,
fetchPolicy: 'no-cache',
variables: {
langMode: await this.state.api.storage.platformSpecificStorage.getItem(
'enOnlyMode',
),
},
})
if (result && result.data) {
let showServicesMenu = false
if (result.data.account) {
showServicesMenu = result.data.account.showServicesMenu
}
const navCollections = result.data.collections || []
<hidden array>.unshift(permanentNavMenuOptions.home)
<hidden array>.push(permanentNavMenuOptions.search)
this.setState({
showServicesMenu,
navCollections,
})
}
}
然后在子组件中,有一个如下所示的componentWillUnmount
生命周期方法:
componentWillUnmount() {
window.removeEventListener('keydown', this.onKeyDown)
console.log(this.videoRef)
if (this.videoRef) {
this.videoRef.currentTime = 0
}
this.updatePositionEvent(false)
if (this.videoRef) {
const v: HTMLVideoElement = this.videoRef
v.removeEventListener('timeupdate', this.checkProgress)
v.removeEventListener('ended', this.endPlayer)
v.removeEventListener('playing', this.playHandler)
if (this.playerPage) {
const p: HTMLDivElement = this.playerPage
p.removeEventListener('focus', this.toggleControls)
}
}
if (this.controlsTimeout) {
window.clearTimeout(this.controlsTimeout)
}
this.props.showNavMenu(this.state.shouldShowNav)
if (this.player) {
this.player.dispose()
}
}
如果组件卸载,我如何实现取消查询的方法?当我加载视频播放器然后取消时,会发生上述错误。