reactjs - 路由器事件在构造函数上使用时会导致错误警告 : Can't perform a React state update on an unmounted component

标签 reactjs next.js next-router

我遇到了这个问题,我尝试将其转换为函数,但 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} />;
}

最佳答案

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

还建议使用 useRouter Hook 中的 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} />;
}

关于reactjs - 路由器事件在构造函数上使用时会导致错误警告 : Can't perform a React state update on an unmounted component,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70035938/

相关文章:

javascript - 为什么一个空的、默认的 NextJS 应用程序的性能分数这么低?

next.js - 如何使用 NextJS Links 处理电话号码?

next.js - 无法在 Vercel 上使用 serverSideTranslations

reactjs - Next.js 路由 "next-connect"用于子路由

javascript - 计算对象属性的重复数组以生成新数组

node.js - Node JS 和 React 出现错误

javascript - 如何修复错误 : _registerComponent(. ..) : Target container is not a DOM element. 错误?

javascript - 在 React 组件之外使用 NextRouter

javascript - Next.js 应用程序在带有 basePath 的子文件夹中,如何使主页在 basePath 之外可用?

javascript - 是否可以在 React Native 中从其无状态组件子级更改父级的状态?