【问题标题】:use NextRouter outside of React component在 React 组件之外使用 NextRouter
【发布时间】:2020-12-27 01:27:49
【问题描述】:

我有一个自定义钩子,它会检查您是否已登录,如果未登录,则将您重定向到登录页面。这是我的钩子的伪实现,假设您没有登录:

import { useRouter } from 'next/router';

export default function useAuthentication() {

  if (!AuthenticationStore.isLoggedIn()) {
    const router = useRouter();
    router.push('/login'); 
  }
}

但是当我使用这个钩子时,我得到了以下错误:

错误:未找到路由器实例。您应该只在应用程序的客户端内使用“next/router”。 https://err.sh/vercel/next.js/no-router-instance

我检查了错误中的链接,但这并没有真正的帮助,因为它只是告诉我将 push 语句移动到我的渲染函数中。

我也试过这个:

// My functional component
export default function SomeComponent() {

  const router = useRouter();
  useAuthentication(router);

  return <>...</>
}

// My custom hook
export default function useAuthentication(router) {

  if (!AuthenticationStore.isLoggedIn()) {
    router.push('/login');
  }
}

但这只会导致同样的错误。

有没有办法允许在 next.js 中路由到 React 组件之外?

【问题讨论】:

    标签: javascript reactjs react-router next.js next-router


    【解决方案1】:

    发生错误是因为在页面首次加载的 SSR 期间,服务器上调用了 router.push。一种可能的解决方法是扩展您的自定义挂钩以在 useEffect 的回调中调用 router.push,确保该操作仅在客户端上发生。

    import { useEffect } from 'react';
    import { useRouter } from 'next/router';
    
    export default function useAuthentication() {
        const router = useRouter();
    
        useEffect(() => {
            if (!AuthenticationStore.isLoggedIn()) {
                router.push('/login'); 
            }
        }, []);
    }
    

    然后在你的组件中使用它:

    import useAuthentication from '../hooks/use-authentication' // Replace with your path to the hook
    
    export default function SomeComponent() {
        useAuthentication();
    
        return <>...</>;
    }
    

    【讨论】:

      【解决方案2】:

      import Router from 'next/router'

      【讨论】:

      【解决方案3】:

      创建一个 HOC 来包装你的页面组件

      import React, { useEffect } from "react";
      import {useRouter} from 'next/router';
      
      export default function UseAuthentication() {
       return () => {
          const router = useRouter();
      
          useEffect(() => {
            if (!AuthenticationStore.isLoggedIn()) router.push("/login");
          }, []); 
      // yous should also add isLoggedIn in array of dependancy if the value is not a function
      
          return <Component {...arguments} />;
        };
      }
      

      主要组件

      function SomeComponent() {
      
      
        return <>...</>
      }
      export default UseAuthentication(SomeComponent)
      

      【讨论】:

      • 这会导致同样的错误:Error: No router instance found. You should only use "next/router" inside the client side of your app.
      猜你喜欢
      • 1970-01-01
      • 2022-11-17
      • 2020-04-26
      • 2020-07-09
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多