1

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

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 组件之外进行路由?

4

3 回答 3

1

import Router from 'next/router'

于 2021-01-12T17:31:31.150 回答
1

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

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 <>...</>;
}
于 2021-02-18T22:03:07.437 回答
0

创建一个 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)
于 2020-09-09T01:53:48.130 回答