获取 URL 参数 (Next.js 13)

问题描述 投票:0回答:7

我正在使用

/app
目录构建 Next.js 13 项目。我有一个问题 - 在根布局中,我有一个永久的导航栏组件,该组件是从
/components/Navbar.jsx
导入的。基本上在
Navbar.jsx
内部,我希望能够访问url中的slug参数,例如:
localhost:3000/:slug
,其中我想要slug id。我已经为该 slug 定义了 Next.js 13 page.jsx。但是如何获取 navbar 组件中的 slug id。我也不想使用
window.location.pathname
,因为当页面路由到不同的 slug 时它不会改变,并且仅在我刷新时才会改变。

我尝试过旧的 Next.js 12 方法:

//components/navbar.jsx;

import { useRouter } from "next/navigation";

export default function Navbar () {
  const router = useRouter();
  const { slug } = router.query;

  useEffect(() => {
    console.log(slug);
  }, []);

  return <p>Slug: {slug}</p>
}

但是它不起作用。

reactjs url next.js
7个回答
15
投票

要获取 Next.js 13 中服务器组件中的 URL 参数,您可以使用 Page 函数的

searchParams
参数。

网址

localhost:3000/?slug

page.js

export default function Page({searchParams}) {
   return <Navbar slug={searchParams}></Navbar>
}

navbar.js

export default function Navbar(props) {
   return <p>Slug: {props.slug}</p>
}

更多信息:https://beta.nextjs.org/docs/api-reference/file-conventions/page


10
投票

另一种方法是使用挂钩

useSearchParams

来自文档

import { useSearchParams } from 'next/navigation';

export default function Page() {
  const searchParams = useSearchParams();

  // E.g. `/dashboard?page=2&order=asc`
  const page = searchParams.get('page');
  const order = searchParams.get('order');

  return (
    <div>
      <p>Page: {page}</p>
      <p>Order: {order}</p>
    </div>
  );
}

5
投票

有 3 种不同的参数变体

  1. 参数
    (/blog/1)
    • 单个参数
    • 多个参数
  2. 搜索参数
    (/blog?postId=123)
    • 单一搜索参数
    • 多个搜索参数
  3. params 和 searchParmas
    (/blog/1?postId=123)

有多种方法可以处理这个问题

  1. 对于参数 -
    UseParams()
'use client'
 
import { useParams } from 'next/navigation'
 
export default function ExampleClientComponent() {
  const params = useParams()
 
  // Route -> /shop/[tag]/[item]
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  console.log(params)
 
  return <></>
}
  1. 对于搜索参数 -
    useSearchParams()
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const search = searchParams.get('search')
 
  // URL -> `/dashboard?search=my-project`
  // `search` -> 'my-project'
  return <>Search: {search}</>
}
  1. 参数和搜索参数均使用
    any
    类型
'use client'

export default function BlogPost(props: any) {

    // URL -> blog/a/b?param1=IamfirstParam&param2=IamsecondParam
    return <div>{props}</div>;

   // Output ->
   //{
   //  params: { blogId: [ 'a', 'b' ] },
   //  searchParams: { param1: 'IamfirstParam', param2: 'IamsecondParam' }
   //}
}
  1. 参数和搜索参数均使用
    defined
    类型
'use client';

// URL -> blog/a/b?param1=IamfirstParam&param2=IamsecondParam

export default function BlogPost({
    params,
    searchParams,
}: {
    params: { blogId: string[] };
    searchParams: { param1: string; param2: string };
}) {


    return (
        <div>
            {params.blogId[0]}
            {params.blogId[1]}
            {searchParams.param1}
            {searchParams.param2}
        </div>
    );
}

有关动态参数的所有可能性,请参阅:如何使用 nextjs 13 进行动态路由?


另请参阅最新的 Nextjs 13 代码模板 Next.js 13+ 强大片段 | TypeScript/Javascript

它包含

ts
js
的广泛代码片段。查找所有片段
此处



4
投票

我不知道问题是否仍然相关,但如果它是数组,您可以使用 NextRequest 包含的方法 nextUrl.searchParams.get 或 getAll

import { NextResponse, NextRequest } from 'next/server';

export async function GET(request: NextRequest) {
  
  const queryParam = request.nextUrl.searchParams.get("queryParam");
  
  return NextResponse.json({ message: 'Query parameter value is ' + queryParam }, { status: 200 });
}

我在端点中使用了它,但对于页面也是如此,必须警告 NextRequest 只能在服务器组件中使用,对于客户端组件,您需要 useRouter 和“使用客户端”


3
投票

为了在 Next.js 13 中使用 typescript 在服务器端组件中获取

params
searchParams
,您应该定义您期望的 params 和 searchParams。例如:

// /app/category/[slug]/page.tsx
// Request URL localhost:3000/category/news?page=2

export default function PostsCategory({ params, searchParams }: { params: { slug: string }; searchParams: { page: string } }) {
  const posts = getPostsByTag(params.slug, ['title', 'date', 'excerpt', 'image', 'slug', 'tags']);
  const currentPage = searchParams && searchParams.page ? Number(searchParams.page) : 1;
  const { slug } = params;

  return (
    <main>
      <PaginatedPosts posts={posts} page={currentPage} title={`${slug}`} />
    </main>
  );
}

2
投票

必须使用

usePathname

import { usePathname } from 'next/navigation';

0
投票

官方文档对此说得非常清楚:https://nextjs.org/docs/app/api-reference/functions/use-search-params#server-components

页数

要访问页面(服务器组件)中的搜索参数,请使用

searchParams
属性。

布局

与页面不同,布局(服务器组件)不会收到

searchParams
属性。这是因为共享布局在导航期间不会重新渲染,这可能会导致导航之间出现陈旧的
searchParams

相反,请在客户端组件中使用 Page

searchParams
属性或
useSearchParams
挂钩,该组件会使用最新的
searchParams
在客户端上重新渲染。

因此,只需制作一个小型客户端组件,该组件将在每次导航时重新渲染,并从布局中引用它。

© www.soinside.com 2019 - 2024. All rights reserved.