路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 React 状态更新

Posted

技术标签:

【中文标题】路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 React 状态更新【英文标题】:Router events cause an error while being used on the constructor Warning: Can't perform a React state update on an unmounted component 【发布时间】:2021-12-30 07:01:32 【问题描述】:

我遇到了这个问题,我尝试将其转换为函数,但 states 没有按预期工作。我该如何解决这个问题?我想在切换路由时创建加载效果而不引起此类问题:

react-dom.development.js?ac89:67 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.
        at Loading (webpack-internal:///./components/loading.js:83:9)
        at MyApp (webpack-internal:///./pages/_app.js:58:27)
        at StyleRegistry (webpack-internal:///./node_modules/styled-jsx/dist/stylesheet-registry.js:231:34)

这是我的代码:

import Router from "next/router";
import  Component  from "react";
import Loader from "./Loader";

export default class Loading extends Component 
  constructor() 
      super();
      this.state = 
        loader: false
      
  

  componentDidMount()
      // Some page has started loading
      Router.events.on("routeChangeStart", (url) => 
        this.setState( loader: true );
      );
         // Some page has finished loading
         Router.onRouteChangeComplete = (url) => 
          this.setState( loader: false );
        ;
  
  componentWillUnmount()

    

  render() 
    return(
      <Loader loading=this.state.loader />
    );
  

我也试过了:

import Router from "next/router";
import  useState  from "react";
import Loader from "./Loader";

export default function Loading ()
  const [loader, setLoader] = useState(false);

  // Some page has started loading
  Router.events.on("routeChangeStart", (url) => 
      setLoader(true);
  );
  // Some page has finished loading
  Router.onRouteChangeComplete = (url) => 
      setLoader(false);
  ;

  return <Loader loading=loader />;

【问题讨论】:

“我尝试将其转换为函数” - 您能否展示您将其转换为函数组件的尝试? 谢谢,我觉得这次成功了onRouteChangeError,给我带来了麻烦 不,没有用。现在我看到了同样的问题。是在 DOM 加载之前还是之前才创建 React 状态? 您需要将componentDidMount 中的代码移动到useEffect 中。 【参考方案1】:

您在componentDidMount 中的代码需要移到useEffect 中。此外,在卸载组件时需要清理对路由器事件的订阅,以防止出现您看到的错误。

还建议使用useRouter 挂钩中的router 实例,而不是直接访问全局路由器对象。

您的函数组件应大致如下所示。

import  useRouter  from "next/router";
import  useEffect, useState  from "react";
import Loader from "./Loader";

export default function Loading () 
    const [loader, setLoader] = useState(false);
    const router = useRouter();

    useEffect(() => 
        const handleRouteChangeStart = (url) => 
            setLoader(true);
        ;
        const handleRouteChangeComplete = (url) => 
            setLoader(false);
        ;

        router.events.on("routeChangeStart", handleRouteChangeStart);
        router.events.on("routeChangeComplete", handleRouteChangeComplete);

        // When the component unmounts, unsubscribe from the router events with the `off` method
        return () => 
            router.events.off("routeChangeStart", handleRouteChangeStart);
            router.events.off("routeChangeComplete", handleRouteChangeComplete);
        ;
    , [router]);
  
    return <Loader loading=loader />;

【讨论】:

以上是关于路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 React 状态更新的主要内容,如果未能解决你的问题,请参考以下文章

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?

无法修复警告检测到重复键:“0”。这可能会导致更新错误

WIFI密码正确但总提示密码错误是啥原因?

如何在事件 onChange 上设置超时

vuejs 3:未捕获的类型错误:对象(...)不是函数[重复]

“警告:无法对未安装的组件执行 React 状态更新。” [关闭]