How can I specify the optional parameters in the dynamic routing?

僤鯓⒐⒋嵵緔 提交于 2020-12-13 03:25:55

问题


Suppose I have a page that will show the details of each chapter in the book. User can navigate to other chapters from that page, as the screen has buttons of chapters in the sidebar, and the main content shows the details of the chapter.

Now the user will navigate to that page from a list of books. At the page information, there's no chapter information of that book.

Now if the URL is \bookSlug, so the page will show the details of the first chapter, even it is not mentioned in the URL, it will fetch the list of chapters then fetch the details of the first chapter from that list. This behaviour remains the same for URL \bookSlug\firstChapterSlug.


So, in react-router I used to do it like this.

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

And on the page, I handle the params, that id the chapterId is undefined to just fetch the first chapter or just fetch the chapter mentioned in the chapterId param.

Now, I'm stuck here,

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

It is just not working, even I have marked the params in the getStaticPaths optional GetStaticPaths<Props, {bookSlug: string, chapterSlug?: string}> s that I can write logic.

How can I achieve that react-router behaviour here in nextJS dynamic routing?


回答1:


Since Next 9.5 you can do it by using optional catch-all routes.

You would have a route like this /[bookId]/[[...chapterId]].

And to navigate, since Next 9.5.3 you don't need "as" property in Link so Next sould handle this correctly : <Link href='/some-book'/>




回答2:


Navigation like that is not possible and incorrect with nextjs, if you provide href='/[bookSlug]/[chapterSlug]' you have to provide 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])

Possible soutions There are two possible solutions for what you are trying to achieve

If you want the route /some-book to match with [bookSlug] and display the page for the book details and only display some chapter you have to create an index.tsx file which will be used to fetch only the book details and data for the first chapter and return a new page component from it. For example, this is what the pages folder structure might look like,

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

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

And you have to explicitly navigate to that page like below

// 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'/>

The second solution is to only keep the [bookSlug] part of the dynamic route and fetch the book details and data for all the chapters and pass it as props. To display each chapter details page make use of shallow-routing.

When it comes to navigating to each chapter you have to make use of router.push instead of the Linkcomponent.

If you were thinking of conditionally returning paths from the function getStaticPaths where you only provide the value for param bookSlug and omit chapterSlug something like { paths: [{ params: { bookSlug: 'some-book'} }]}, this will not work.

For /[bookSlug]/[chapterSlug].js if you try to do something like that it will generate a error at build time

Error: A required parameter (chapterSlug) was not provided as a string in getStaticPaths for /[bookSlug]/[chapterSlug]



来源:https://stackoverflow.com/questions/62625134/how-can-i-specify-the-optional-parameters-in-the-dynamic-routing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!