0

我遇到了一个大型 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()
    }
  }

如果组件卸载,我如何实现取消查询的方法?当我加载视频播放器然后取消时,会发生上述错误。

4

0 回答 0