嗨嗨嗨!昨天看完怎麽抓取资料的方式会影响到网页的渲染模式之後,今天的主题是 Next.js 的 Pages 与 Routing。Next.js 的 routing 方式跟一般 React 使用的 react-router
不一样,它采用 file-based routing。
File-based routing 的意思是每个档案代表一个 route,而档案名称 (file name) 会变成 route 的 path name (路径名称)。Next.js 会把 pages
资料夹 / 目录里面的所有档案看成 route (路径) 的一部分,还不是很懂吗?我们看看下面的例子~
pages/index.js
代表 /
routepages/about.js
代表 /about
route每个 index 档案代表根目录,所以
pages/index.js
代表 /
routepages/posts/index.js
代表 /posts
route每一层资料夹每一层目录会是 route 的一部分,所以
pages/posts/index.js
代表 /posts
routepages/posts/first.js
代表 /posts/first
routepages/categories/lifestyle/fashion.js
代表 /categories/lifestyle/fashion
route如果上面的 routes 都要我们自己定义每一个 file name 当 path name,那当我们有一系列的页面怎麽办?或是如果我们想要把资料库里的每一条资料写个页面怎麽办?或是像iT邦帮忙的网址 https://ithelp.ithome.com.tw/users/20141378
应该不会是我们要新增 20141378 个页面档案吧?这时候我们需要 dynamic routes 来帮助我们!
pages/posts/[pid]/index.js
代表 /posts/1
,/posts/2
,···pages/posts/[pid]/comments/index.js
代表 /posts/1/comments
,/posts/2/comments
,···pages/posts/[pid]/comments/[cid].js
代表 /posts/1/comments/1-1
,/posts/2/comments/2-1
,···或是iT邦帮忙的网址 https://ithelp.ithome.com.tw/users/20141378
需要一个档案 pages/users/[uid].js
。这些动态的资讯可以在 route.query
物件里面看到,/posts/a/comments/a-1?utm_source=ithome
的 query
物件会长这样:
{ "pid": "a", "cid": "a-1", "utm_source": "ithome" }
属於 dynamic routes 的一种,不过 catch all 的意思是不需要一个一个定义动态的部分,把所有动态的资讯抓起来,让 route 比较弹性,写法跟其余参数(rest parameter)一样。
pages/posts/[...slug].js
可以代表 /posts/a
也可以是 /posts/a/b
,/posts/a/b/c
等slug
可以是 param
或是其他东西都可以,这些动态资讯也会出现在 query
物件里面,例如 /posts/a/b/c
的 query
会是:
{ "slug": ["a", "b", "c"] }
知道了 catch all routes 之後,还有另一种更有弹性的 dynamic routes,只要把 catch all 的 [...slug]
改成 [[...slug]]
就会变成 optional catch all。意思是 slug
这个 array (阵列) 可以是不存在的,
pages/posts/[[...slug]].js
可以代表 /posts/a
也可以是 /posts/a/b
,/posts/a/b/c
等,不过也可以代表 /posts
所以 query
物件会是空物件 {}
。
注意:
query
在 static (静态) 页面在第一次渲染的时候不会有东西,就是一个空物件{}
,等到 hydration 完成之後,query
才会被更新
继续到下一个章节之前,我们复习一下~
虽然 routing 方式不太一样,不过 Next.js 还是跟 SPA (Single-page Application) 一样可以做 client-side routing,意思是换页的时候浏览器不用重新 reload,使得整个体验非常顺。Next.js 提供两种方法:
<Link>
(next/link
)useRouter
(next/router
)next/link
提供 Link
component 可以直接用在我们的 react components 里面,跟 react-router-dom
里的 Link
差不多的用法。当我们想要在画面上显示一个连结的时候,可以用 Link
,他底层用 HTML 的 a
实作出来的。比较特别的是,当使用者画面上有显示 <Link />
components, Next.js 会把所有采用 SSG / ISR 的页面先做 prefetch (事先抓取) 这些页面的档案与资料,所以当使用者点下其中一个连结,浏览器可以马上显示新的画面不需要等待,提升使用者换页的体验。想要用 Link
有几种方法:
import Link from "next/link"
function Home() {
return (
<div>
<Link href="/">
<a>Home</a>
</Link>
<Link href="/about">
<a>About</a>
</Link>
</div>
)
}
export default Home
用 string
(字串) 当 href
,"/"
会连到 pages/index.js
的档案,然後 "/about"
会连到 "pages/about.js"
档案。
import Link from "next/link"
function Posts({ posts }) {
return (
<div>
{posts.map(post => (
<Link href={`/posts/${post.id}?utm_source=ithome`}>
<a>Post #{post.id}</a>
</Link>
))}
</div>
)
}
export default Posts
想要导页去 dynamic routes 一样可以把 path 组成 string
给 href
,例如 /posts/${post.id}
然後 post.id
是动态的。或是可以把 path 拆成 object (物件) 给 href
,像这样~
{
pathname: "/posts/[pid]", // 跟 file name 一样
query: { pid: post.id }, // path 中动态的部分,在这例子是 pid
}
query
不只可以包含 path 中的动态部分,也可以包含 URL 中的 query string,像 /posts/1?utm_source=ithome
这个 path 可以写成:
{
pathname: "/posts/[pid]",
query: { pid: post.id, utm_source: "ithome" },
}
除了把连结显示在画面上让使用者点下去以外,我们也可以用程序码做导页,就是用 useRouter
。useRouter
回传 router
物件,里面包含各式各样与 routing 有关的资讯,例如 pathname
(当下的路径), query
(该路径的 query string), isFallback
(服务器是否正在显示备份版本的页面), isReady
(浏览器是否已经拿到 route 相关资讯) 等资讯。不过 router
还包含一些 methods,有几个跟导页有关的:
什麽是 shallow routing 或是浅层换页 (浅层路由)?换页的过程中服务器不会重跑 data fetching 的 functions,也不会 re-render (重新渲染) 整个页面保持该页的状态。虽然页面不会被换掉,可是 router
中的 pathname
和 query
会拿到最新值。
router.push("/?id=1", undefined, { shallow: true })
不过要注意,shallow routing 只能用在同一个页面,/?id=1
换去 /about?id=1
是不同的页面,所以 Next.js 会跟平常一样去下载新的页面。
File-based routing 是不是看起来很棒呢?~ 不过还是要注意小细节喔,避免遇到 routing 相关问题。明天跟大家分享让 Next.js 变成一个全端框架的原因,就是 API routes!
祝大家中秋节快乐!
晚安 <3
<<: Consistency and Consensus (4-1) - Atomic Commit and Two-Phase Commit(2pC)
>>: Day20 测试写起乃 - $CHILD_STATUS
前言: ConstraintLayout讲完了,画面画好了那是用在那呢? 那就是要放在 Activi...
感谢大家花宝贵的时间阅读这系列的文章,由於篇幅有限,其实还有很多主题无法尽录,不过希望阅读过後,大...
前言 今天要来介绍一点 for 回圈,因为接下来的 list 会用到!会介绍一些基本的 for 的用...
L2 关联式模型 2-1 关联式模型结构 表(tables):一个关联式资料库包含了表的集合 关联(...
Container会飞 在AWS ECS上目前有提供EC2 mode, Fargate, ECS A...