路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 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 状态更新的主要内容,如果未能解决你的问题,请参考以下文章
为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?