javascript - 在组件已卸载后,如何取消解析 promise 的状态更改?

标签 javascript reactjs

背景:

我想知道如何消除这个错误:

Warning: Can't perform a React state update on an unmounted component.

我想我确切地知道为什么会出现此错误:

我有一个登录路线。我在 useEffect 中有一小段代码可以执行此操作:

if (!auth.isEmpty && auth.isLoaded) { 历史记录.push("/"); }

因此,当有人访问我的页面/登录并且已经登录时,他会被重定向到主页。这工作正常但是:

问题:

当他没有登录时我有一个小小的登录功能:

const signin = async (e: React.MouseEvent) => {
    setIsLoading(true);
    e.preventDefault();

    try {
      const user = await firebase.login({ email, password });
      setIsLoading(false);
      if (user) {
        history.push("/");
      }
    } catch (error) {
      setIsLoading(false);
      setError(error.message);
    }
  };

因此,当用户按 Enter 时,如果没有错误,他会被重定向到主页。它工作正常,但我在控制台中收到此错误,因为我设置了状态,并且 useEffect 中的代码片段将我路由到/Home,但 firebase 尚未完成 promise 。当它完成时,它尝试设置状态,但组件已经卸载。

我尝试了什么

我添加了一个 isMounted Hook 并将我的登录函数更改为如下所示:

const signin = async (e: React.MouseEvent) => {
    e.preventDefault();

    if (isMounted) {
      setIsLoading(true);
      try {
        const user = await firebase.login({ email, password });
        setIsLoading(false);
        if (user) {
          history.push("/");
        }
      } catch (error) {
        setIsLoading(false);
        setError(error.message);
      }
    }
  };

但路线更改时仍然出现相同的错误。

其他信息

不要对这两种加载状态 auth.isLoaded (来自 react-redux-firebase)和 isLoading (我自己的状态)。基本上我这样做的原因是,因为当某人已经登录然后转到/signin 时,他会看到登录表单一小会儿,因为 firebase 还不知道用户是否已通过身份验证,所以我这样处理,因此用户明确地看到一个旋转器,然后在已经登录的情况下被重定向。

这个小问题怎么解决呢?

最佳答案

您可以为此使用 React hooks。当组件从屏幕上取消显示时,将调用 useEffect 返回方法。这就像基于类的 React 中的 compomentdidunmount。

将全局变量 _isMounted 声明为 false。当 useEffect 被调用时,它会变为 true 并且组件会显示在屏幕上。 如果组件被卸载,则调用 useEffect 的返回方法,并将 _isMounted 设置为 false;


在更新状态时,您可以使用 _isMounted 变量检查组件是否已安装。

var _isMounted = false;

const fetchuser = () => {
   if(_isMounted)
   {
       // code
   }
}

useEffect(() => {

    _isMounted = true;
    // your code;

   return()
   {
      _isMounted = false;
      console.log("Component Unmounted");
   }

},[])

关于javascript - 在组件已卸载后,如何取消解析 promise 的状态更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61385318/

相关文章:

javascript - 如何在初始化许多视频时获取 Plyr 当前实例

reactjs - 无法使用 React-Query + Graphql-Request 在 useQuery 中传递参数

javascript - 为什么 React .setState() 需要一组额外的括号?

css - 内部元素滚动上的 Antd 选择和自动完成列表元素 'stick'

javascript - 模拟鼠标滚动事件

javascript - React onClick 事件不会触发 setState

javascript - 当鼠标悬停在该行的任意位置时,我可以使 TableRow 列中的图标改变颜色吗?

javascript - react native (ios)。 "saveToCameraRoll"错误 - "PHPhotosErrorDomain error -1"

javascript - 检测 Ajax 调用内 div 的点击

javascript - 安卓:用JS设置window.location