在Next.js中获取URL路径名

142

我有一个登录页面和布局组件。布局组件有标题。我不想在登录页面显示标题,并且为此我想要获取URL路径名。根据路径名显示标题。

import * as constlocalStorage from '../helpers/localstorage';
import Router from 'next/router';

export default class MyApp extends App {
    componentDidMount(){
        if(constlocalStorage.getLocalStorage()){
            Router.push({pathname:'/app'});
        } else{
            Router.push({pathname:'/signin'});
        }

    }

    render() {
        const { Component, pageProps } = this.props
        return (
//I want here pathname for checking weather to show header or not
                <Layout>
                    <Component {...pageProps} />
                </Layout>
        )
    }
}
请帮忙。

19个回答

153

如果你想在应用程序中的任何函数组件内访问router对象,可以使用useRouter钩子,以下是使用方法:

import { useRouter } from 'next/router'

export default function ActiveLink({ children, href }) {
  const router = useRouter()
  const style = {
    marginRight: 10,
    color: router.pathname === href ? 'red' : 'black',
  }

  const handleClick = e => {
    e.preventDefault()
    router.push(href)
  }

  return (
    <a href={href} onClick={handleClick} style={style}>
      {children}
    </a>
  )
}
如果useRouter不适合您,withRouter也可以将相同的路由器对象添加到任何组件中,下面是使用它的方法:

如果useRouter不适合您,withRouter也可以将相同的路由器对象添加到任何组件中,下面是使用它的方法:

import { withRouter } from 'next/router'

function Page({ router }) {
  return <p>{router.pathname}</p>
}

export default withRouter(Page)

https://nextjs.org/docs/api-reference/next/router#userouter


5
API路由怎么办?如何在Next.js的API路由中访问路由器实例? - Camilo

65
你可以使用asPath属性,它将返回浏览器中显示的路径(包括查询参数),不受配置的basePathlocale的影响:
const { asPath } = useRouter()

53
假设某页面的完整URL为“abc.com/blog/xyz”,与该路由相匹配的组件文件名是“./pages/blog/[slug].js”。 useRouter() 钩子返回一个路由对象,该对象有两个属性可用于获取路径名。 一个是 asPath 属性, 另一个是 pathname 属性。 asPath 属性包含从URL中提取的路径名,即 /blog/xyz, 但是pathname 属性包含项目目录的路径名,即 /blog/[slug]。 示例实现。
// .pages/blog/[slug].js

import { useRouter } from 'next/router';

const BlogSlug = () => {
  const { asPath, pathname } = useRouter();
  console.log(asPath); // '/blog/xyz'
  console.log(pathname); // '/blog/[slug]'
  return (
    <div></div>
  );
}

export default BlogSlug;

20
如果您正在使用 Next.js 13,请使用 usePathname 而不是 useRouter
'use client';

import { usePathname } from 'next/navigation';

export default function MyComponent() {
  const currentPage = usePathname();
  return <div>{currentPage}</div>;
}

14
有没有想过如何使用服务器组件来完成这个任务? - Steven
你帮我节省了时间,非常感谢! - Dave Lee
1
从服务器组件获取URL:import { headers } from 'next/headers' https://stackoverflow.com/a/76312149/3212572 - undefined

9
可能有点晚了,但只需使用 router.pathname
function MyComp() {
    const router = useRouter();

    return (
        <a className={router.pathname === '/some-path' ? 'currentCSS' : 'defaultCSS'}>
            Some link
        </a>
    );
}

9
要充分使用Next.js提供的SSR功能,您可以在getInitialProps中使用context对象,该对象包含pathname。然后,您可以将此pathname作为props传递给组件。请参考以下示例:
class Page extends React.Component {
 static getInitialProps({ pathname }){
  return { pathname }
 }
 render() {
  return <div>{this.props.pathname === 'login' ? 'good' : 'not good'}</div>
 }
}


3

在app.js文件中,无法访问路由器或useRouter()选项以访问当前路径。这不是客户端渲染,因此访问当前路径的唯一方法是从getInitialProps()getServerSideProps()调用中传递它到您的App组件,然后在那里访问它以根据当前路由开发您的逻辑。


3
在 Nextjs 13.4+ 中,更推荐使用来自 next/navigation 的 usePathName。
import { usePathname } from "next/navigation";

export function Component() {
    const pathname = usePathname();
    console.log(pathname); // Your path name ex: /product
}

根据路径名,如果您想显示活动链接,请参考下面的链接: 当路由在Next.js中处于活动状态时,目标活动链接

当使用 "npm build" 命令时,此页面无法路由,你如何解决? - Man Man Yu

2

Next.js v13.4.3

这对我来说很有效

import { usePathname} from 'next/navigation'

const pathname = usePathname();

console.log(pathname)

你的回答可以通过提供更多支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人能够确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - Community
当使用npm build时,无法路由到此页面,你如何解决? - Man Man Yu
看起来像是一个感谢回答:https://stackoverflow.com/a/75926922/6126373 - undefined

2
对于那些从Next.js Page-Router迁移到App-outer V13+的用户,
我正在寻找获取完整URL的方法。
下面是根据Next.js文档推荐的正确做法。
    'use client'
 
import { useEffect } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'
 

    export function NavigationEvents() {
  const pathname = usePathname()
  const searchParams = useSearchParams()
 
  useEffect(() => {
    const url = `${pathname}?${searchParams}`
    console.log(url)
    // You can now use the current URL
    // ...
  }, [pathname, searchParams])
 
  return null
}

请注意,您应该在客户端组件中使用此功能,而不是服务器组件。这意味着您需要在组件页面顶部添加"use client"。
如果您想在服务器组件中执行此操作,您将需要将服务器组件作为props传递给客户端组件。
场景:您需要在服务器组件中使用URL,但不能使用usePathname和useSearchParams,因为它们只允许在客户端组件中使用。那么在这种情况下(以及任何需要在服务器组件中执行仅限于客户端组件的操作的情况),文档推荐采取什么措施呢?
您可以在客户端组件中执行所需操作,然后将服务器组件作为prop传递给客户端组件。这个prop的值可以是URL或其他您想要传递给服务器组件的数据。
简单解释:您将在服务器组件中添加一个名为URL的prop,在客户端组件中,您将使用usePathname和useSearchParams获取的URL作为prop值传递给URL prop。
如果您想知道为什么不能直接导入服务器组件:
根据文档:
不支持的模式:将服务器组件导入到客户端组件中 不支持以下模式。您不能将服务器组件导入到客户端组件中:

这里是来自文档的解释:

将服务器组件作为属性传递给客户端组件

链接:

关于新路由更新的文档:https://nextjs.org/docs/app/api-reference/functions/use-router

关于 usePathname 的文档:https://nextjs.org/docs/app/api-reference/functions/use-pathname

关于 useSearchParams 的文档:https://nextjs.org/docs/app/api-reference/functions/use-search-params


服务器/客户端组件文档目前还在进行中,所以不要抱太大期望。 - morganney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接