如何在动态路由中指定可选参数?

时间:2020-06-28 16:14:36

标签: next.js

假设我有一个page,它将显示书中每章的详细信息。用户可以从该页面导航到其他章节,因为屏幕的侧栏中有章节按钮,主要内容显示了该章节的详细信息。

现在,用户将从书籍列表导航至该页面。在页面信息中,没有该书的章节信息。

现在,如果URL为\bookSlug,那么该页面将显示第一章的详细信息,即使URL中未提及,它也会获取各章的列表,然后获取第一章的详细信息从该列表中。 URL \bookSlug\firstChapterSlug的行为仍然相同。


因此,在react-router中,我曾经这样做过。

<Route path={'/:bookId/:chapterId?'} component={ChapterDetails} >

在页面上,我处理这些参数,未定义chapterId的ID只是获取第一章或仅获取ChapterId参数中提到的章节。

现在,我被困在这里,

<Link href={'/[bookSlug]/[chapterSlug]' as={'/someBookName'} >

即使我已经在getStaticPaths可选GetStaticPaths<Props, {bookSlug: string, chapterSlug?: string}>中标记了我可以编写逻辑的参数,这还是行不通的。

如何在nextJS动态路由中实现该react-router行为?

2 个答案:

答案 0 :(得分:1)

从9.5开始,您可以使用optional catch-all routes

您将有一条/[bookId]/[[...chapterId]]这样的路线。

并进行导航,自Next 9.5.3 you don't need "as" property in Link起,因此Next灵魂可以正确处理此问题: <Link href='/some-book'/>

答案 1 :(得分:0)

nextjs无法进行这样的导航,并且导航不正确,如果您提供 onValueChanged ,则必须提供 href='/[bookSlug]/[chapterSlug]'

as='/some-book/some-chapter'

<Link href={'/[bookSlug]/[chapterSlug]' as={'/someBookName'} /> // this will produce an error

可能的状态 针对您要实现的目标有两种可能的解决方案

如果您希望路线Error: The provided as value (/some-book) is incompatible with the href value (/[bookSlug]/[chapterSlug])/some-book匹配并显示页面以显示书籍详细信息,并且仅显示某些章节,则必须创建一个[bookSlug]文件,该文件将用于仅获取第一章的书籍详细信息和数据,并从中返回一个新的页面组件。例如,这就是index.tsx文件夹结构的样子,

pages

并且您必须像下面这样明确地导航到该页面

- pages
  - [bookSlug]
     - index.tsx  
     - [chapterSlug].tsx

// index.tsx can be used to fetch and  display the book details and first chapter

第二种解决方案 是仅保留动态路线的// for navigating to /some-book (which will display only the first chapter) <Link href='/[bookSlug]' as={'/some-book'} /> // for navigating to /some-book/some-chapter <Link href='/[bookSlug]/[chapterSlug]' as='/some-book/some-chapter'/> 部分,并获取所有章节的书籍详细信息和数据,并将其作为道具。要显示每个章节的详细信息页面,请使用shallow-routing

导航到每一章时,您必须使用[bookSlug]而不是router.push组件。

如果您打算从函数Link中有条件地返回paths,而在该函数中,您仅提供参数getStaticPaths的值,而忽略bookSlug之类的chapterSlug这将不起作用

对于{ paths: [{ params: { bookSlug: 'some-book'} }]},如果您尝试执行类似的操作,则会在构建时生成错误

/[bookSlug]/[chapterSlug].js