javascript - 取消useEffect的Async with TypeScript,正确的方法

标签 javascript reactjs typescript use-effect

这个简单的例子让我感到悲伤:

useEffect(() => {
  axios.get(...).then(...).catch(...)

}, [props.foo])

warning: can't perform a react state update on an unmounted component

做了一些研究并 this one更容易理解。 TypeScript 似乎不喜欢这种方法,因为 useEffect 应该返回 void。

useEffect(() => {
  let isSubscribed = true

  axios.get(...).then(...).catch(...)

  return () => (isSubscribed = false)

}, [props.foo])

typescript :

/**
     * Accepts a function that contains imperative, possibly effectful code.
     *
     * @param effect Imperative function that can return a cleanup function
     * @param deps If present, effect will only activate if the values in the list change.
     *
     * @version 16.8.0
     * @see https://reactjs.org/docs/hooks-reference.html#useeffect
     */
    function useEffect(effect: EffectCallback, deps?: DependencyList): void;

如何使用 TS 在我的 useEffect 中实现 isSubscribed

谢谢。

最佳答案

useEffect 本身返回 void,但提供给 useEffect 的函数类型为 EffectCallback。定义为:

// NOTE: callbacks are _only_ allowed to return either void, or a destructor.
// The destructor is itself only allowed to return void.
type EffectCallback = () => (void | (() => void | undefined));

Source

这意味着您的效果回调实际上可以返回一个函数,该函数必须返回 voidundefined

现在您可以解决您的问题,以避免使用 isSubscribed 变量调用 setState。但另一种(也许更好)的方法是彻底取消请求。

useEffect(() => {
  const CancelToken = axios.CancelToken;
  const source = CancelToken.source();

  axios.get('...', { cancelToken: source.token }).then(/**/).catch(e => {
    if (axios.isCancel(thrown)) {
      console.log('Request canceled', thrown.message);
    } else {/* handle error */}
  });

  return () => source.cancel();
}, [props.foo])

这也记录在 README 中.

您当前代码的问题是,您的析构函数返回 bool 值isSubscribed。无需返回它,只需将赋值放入函数体即可:

return () => {
  isSubscribed = false;
}

关于javascript - 取消useEffect的Async with TypeScript,正确的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60506312/

相关文章:

javascript - 传递给createMediaElementSource的HTMLMediaElement具有跨源资源,节点将输出静音

javascript - 如何将等待与 setTimeout 和 setInterval 一起使用?

javascript - 水平 slider 上的标记

javascript - 在 javascript 中从表单中换行输入文本

javascript - 向可能有或没有查询参数的 URL 添加参数?

javascript - 使用和不使用构造函数将函数传递给状态的区别

javascript - Materialisecss 的 SideNav 在 React Web App 中停止工作

javascript - 如何使用SVG制作半圆装载机?

javascript - TypeScript 中的正则表达式

angular - Angular 12 中复选框更改处理函数的 Jasmine 测试