基础知识
渲染方式
next.js 有两种预渲染方式:
- 编译时渲染 SSG(Static Site Generation)
- 升级版 ISR(Incremental Static Regeneration)
- 服务端渲染 SSR(Server Side Rendering)
SSG 通过 getStaticProps 来实现,html页面会在编译时生成,如果具有动态参数的静态页面(即该组件对应的静态页面需要渲染多次),还需要配合 getStaticPaths 来生成。可以通过 revalidate 参数来指定页面有效期,超时将重新生成静态 html 页面。
SSR 通过 getServerSideProps 来实现。其原理是通过 react 的 renderToString/renderToNodeStream 生成 html,然后在客户端调用 ReactDOM.hydrate 来进行事件绑定。
和渲染相关的函数主要有以下几个,只能存在于页面组件中:
- getStaticProps / getStaticPaths:编译时运行,没有相关函数默认是这种
- getServerSideProps:服务端运行
- getInitialProps:第一次在服务端运行,后面返回该路由时在客户端运行(暂不知道该函数使用场景)
html文件只在页面刷新时请求,后续页面切换使用本地路由进行切换(同构渲染的方式),只获取对于页面的json数据(我们在进行路由切换时,network中可以看到json数据返回,对应页面的getStaticProps或getServerSideProps的返回)
api模块
next.js 路由除了生成页面之外,也可以进行 api 的开发,pages/api 目录下的任何文件都将作为 API 端点映射到 /api/*,这得益于 next.js 的node运行环境。例如 pages/api 有一个 list.js 文件,那么 /api/list 将是一个接口,list.js 文件需要导出一个默认的处理函数。
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
有了这样一种机制,我们就可以用node的一些库做些事情。在实际开发中,有用到的位置:
- 图片下载及加水印的功能:在前端进行文件或者图片过程中,经常会碰到跨域问题,跨域问题配置好后,使用前端下载方式会存在兼容性问题,特别是在移动端(比如默认打开?)。这个使用可以使用next.js api的方式在后端请求后,然后header中加入
Content-Disposition: attachment; filename="xxx.jpeg"等信息,明确告诉为下载文件。这样的好处既不存在跨域问题,又不存在兼容性问题,若需要图片加水印,我们也可以在api中使用sharp库很容易的进行实现。
我们还可以对api进行一些配置,具体可以查看这里。比如当需要使用 formidable 进行 formData 的读取,需要关闭 bodyParser:
export const config = {
api: {
bodyParser: false,
},
}
图片组件及优化
layout处理
_app.tsx
实战记录
如何在页面间传值
传值很简单,可以通过query传值:
router.push({
pathname: '/test',
query: {
id: 123,
name: "Gary"
}
})
这样页面跳转之后,不好的地方是我们的url上会多出很多 query 参数:/test?id=123&name=Gary,若用户刷新的话页面 url 不会变,参数还会保留,这是我们需要在读取了参数之后,恢复成纯净的 path 或者删除某些参数,这个时候我们可以使用 next/router 中的浅路由。
function removeQuery(router, keys = undefined) {
if (!router) {
return
}
const { pathname, query } = router
let newQuery = undefined
if (keys && keys.length > 0) {
newQuery = { ...query }
keys.forEach((key) => {
delete newQuery[key]
})
}
// 我们删除了部分或着全部的query后,使用浅路由(对应shallow: true)的方式进行replace
router.replace({ pathname, query: newQuery }, undefined, { shallow: true })
}
浅路由跳转,不会请求服务端进行页面参数的获取,即对 getStaticProps, getServerSideProps 或 getInitialProps 参数的获取。