Node-web03_03Next

Next深入2

SSR

SSG 存在问题

跟用户数据相关的时候,我们必须获取用户数据后,在渲染页面,这样就无法静态化

  • 虽然也能把用户内容静态化,但是新浪微薄,几亿个用户,难道生产那么多html?
  • 数据更新快,用户自己改身份信息 年龄,昵称等

咋办?

  • BSR 客户端渲染,下拉更新
  • SSR 服务端渲染,下拉更新
  • 但是不能用 getStaticProps
    • 因为这个是 SSG
    • 它是 yarn build 后
  • 可用 getServerSideProps(context:NextPageContext)

获取用户浏览器信息

  • 不同浏览器user-agent不同

  • 定义 getServerSideProps 函数

  • pages/posts/index_ssr.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { GetServerSideProps, NextPage } from 'next';
import React from 'react';
type Props = {
browser: string;
}
const Index_SSR: NextPage<Props> = (props) => {
return (
<>
<div>SSR服务端生成
你的浏览器是:{props.browser}
</div>
</>
)
}

export default Index_SSR;

export const getServerSideProps: GetServerSideProps = async (context) => {
const ua = context.req.headers['user-agent'];
return {
props: {
browser: ua
}
}
}

getServerSideProps

  • 运行时机
    • 无论开发还是生产环境
    • 都是在请求后运行 getServerSideProps
  • 回顾 getStaticProps
    • 开发环境,每次请求后运行
    • 生产环境,build时运行一次
  • 参数
    • context 类型为 NextPageContext
    • context.req / context.res 可以获取请求和响应
    • 一般只用 context.req

SSR缺点

  • 无法获取客户端信息,如浏览器窗口大小

三种渲染方式如何选择

1
2
3
4
5
6
7
8
9
10
11
if(有动态内容吗?){
if(跟客户端相关?){
// 跟请求用户数据相关
return BSR || SSR
}else{
// 跟用户数据无关
return SSG
}
}else{
return 直接html
}

升级SSG:文章详情

  • step01 修改跳转链接

    • pages/posts/index_ssg.tsx
      1
      <Link href={`/posts/${p.id}`}>{p.id}</Link>
  • step02 新建 pages/posts/[id].tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { getPost, getPostIds, Post } from "lib/posts";
import { NextPage } from "next";

type Props = {
post: Post
}
const postShow: NextPage<Props> = (props) => {
const { post } = props
return (
<div>
文章详情
<h1>{post.title}</h1>
<article>
{post.content}
</article>

</div>
)
}

export default postShow;

export const getStaticPaths = async () => {
const idList = await getPostIds();
console.log(idList)
return {
paths: idList.map(id => ({ params: { id: id } })),
fallback: false
}
}

export const getStaticProps = async (x: any) => {
const id = x.params.id;
const post = await getPost(id);
return {
props: {
post: JSON.parse(JSON.stringify(post))
}
}
}

pages/posts/[id].tsx的作用

  • 声明路由 /posts/:id
  • 同时是 /posts/:id的页面实现程序

你需要实现三个东西

  • PostsShow组件 从props里接受 post数据
  • 实现 getStaticProps,从第一个参数接受 params.id
  • 实现 getStaticPaths,返回 id列表

fallback的作用

是否自动兜底