RxJS + React 结合使用时,出现了 “setState called on an unmounted component” 错误,如何解决?

阅读时长 4 分钟读完

RxJS + React 结合使用时,我们经常会遇到 “setState called on an unmounted component” 错误。这个错误的原因是,当使用 RxJS 发出一个请求时,在得到回应之前组件已经被卸载了,而我们又在卸载后的组件上调用了 setState() 方法。这样会导致 React 抛出一个错误。

那么如何解决这个问题呢?下面我们提供几种解决方案。

解决方案一:使用 takeUntil 操作符

使用 takeUntil 操作符可以用来取消掉我们之前发送的请求,从而避免发生上述错误。我们可以在 componentWillUnmount 中通过 unsubscribe 取消我们的请求。示例如下:

-- -------------------- ---- -------
------ ------ - --------- - ---- --------
------ - ------- - ---- -------
------ - --------- - ---- -----------------

----- --- ------- --------- -
  ------------------ -
    -------------
    ---------- - -
      ----- -----
    --
    ----------------- - --- ----------
  -

  ------------------- -
    ------------------
      --------- -- -----------
      -----------------------------------
      --------------- -- -
        --------------- ---- ---
      ---
  -

  ---------------------- -
    -------------------------
    -----------------------------
  -

  -------- -
    ----- - ---- - - -----------
    ------ ---------- - ------------ - --------------------
  -
-

在上面的代码中,我们使用了 takeUntil 操作符取消掉之前发送的请求。在 componentWillUnmount 中,我们首先调用 this.unsubscribe$.next() 来关闭订阅,接着调用 this.unsubscribe$.complete() 来完成 Observable,然后再调用 setState() 方法,这样就避免了上述错误的发生。

解决方案二:使用 switchMap 操作符

我们还可以使用 switchMap 操作符来解决这个问题,示例如下:

-- -------------------- ---- -------
------ ------ - --------- - ---- --------
------ - --------- - ---- -------
------ - --------- - ---- -----------------

----- --- ------- --------- -
  ------------------ -
    -------------
    ---------- - -
      ----- -----
    --
  -

  ------------------- -
    ------------------- ------------
      ------------------ -- --------------------
      --------------- -- -
        --------------- ---- ---
      ---
  -

  ---------------------- -
    -------------------------
    -----------------------------
  -

  -------- -
    ----- - ---- - - -----------
    ------ ---------- - ------------ - --------------------
  -
-

在上面的代码中,我们使用了 switchMap 操作符来解决这个问题。在 componentDidMount 中,我们监听了 document 的 mousemove 事件,并通过 switchMap 这个操作符切换 Observable 对象。当有新的 mousemove 事件触发时,我们就发送了一个新的请求。这样即使组件被卸载了,我们也不会发送不必要的请求,从而避免了上述错误的发生。

总结

RxJS 是一个强大的库,可以用于处理复杂的异步事件。但是在使用 RxJS 和 React 结合时,我们需要小心处理组件的生命周期和状态。对于 “setState called on an unmounted component” 错误,我们可以选择使用 takeUntil 或 switchMap 操作符来取消之前发送的请求,从而避免发生错误。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64facf37f6b2d6eab319b48d

纠错
反馈