- 客户端渲染
- 只在浏览器上执行的渲染
- 用JS,Vue,React创建HTML
- 静态页面生成(SSG)
- Static Site Generation,解决白屏问题,SEO问题
- 无法生成用户相关内容(所有用户请求的结果都一样)
- 页面静态化,把PHP提前渲染成HTML
- 服务端渲染(SSR)
- 解决白屏问题,SEO问题
- 可以生成用户相关内容(不同用户结果不同)
- PHP,Python,Ruby,Java后台的基本功能
- 不同的是,Next.js的预渲染可以与前端React无缝对接
- 注意:SSR和SSG都属于预渲染Pre-rendering
BSR 客户端渲染
客户端渲染: 数据一开始不在页面上,是在AJAX请求之后,才在页面上的。
安装axios
yarn add axios
yarn add @types/axios
创建/pages/posts/index.tsx
发送请求给之前写好的拿博客文章的api
写一个loading和文章列表为空的处理:
import {NextPage} from 'next';import axios from 'axios';import {useEffect, useState} from 'react';type Post = {id: string,date: string,title: string}const PostsIndex: NextPage = () => {const [posts, setPosts] = useState<Post[]>([]);const [isLoading, setIsLoading] = useState(false);const [isEmpty, setIsEmpty] = useState(false);useEffect(() => {setIsLoading(true);axios.get('/api/v1/posts').then(res => {setPosts(res.data);setIsLoading(false);if (res.data.length === 0) {setIsEmpty(true);}}, () => {setIsLoading(false);});}, []); //空数组是为了只在第一次渲染的时候触发return (<div><h1>文章列表</h1>{isLoading ? <div>加载中</div> :isEmpty ? <div>文章列表为空</div> :posts.map(p => <div key={p.id}>{p.id}</div>)}</div>);};;export default PostsIndex;
效果

封装代码:自定义Hooks
新建一个文件/hooks/usePosts.tsx
把上面/posts/index.tsx里面的用到hooks的东西剪切过来
然后把需要的东西isLoading之类的 return出去
import {useEffect, useState} from 'react';import axios from 'axios';type Post = {id: string,date: string,title: string}export const usePost = () => {const [posts, setPosts] = useState<Post[]>([]);const [isLoading, setIsLoading] = useState(false);const [isEmpty, setIsEmpty] = useState(false);useEffect(() => {setIsLoading(true);axios.get('/api/v1/posts').then(res => {setPosts(res.data);setIsLoading(false);if (res.data.length === 0) {setIsEmpty(true);}}, () => {setIsLoading(false);});}, []); //空数组是为了只在第一次渲染的时候触发return {posts,setPosts,isLoading,setIsLoading,isEmpty,setIsEmpty}};
/posts/index.tsx 就引入上面的usePosts,并解构出想要的数据
import {NextPage} from 'next';import {usePost} from '../../hooks/usePosts';const PostsIndex: NextPage = () => {const {isLoading , isEmpty, posts} = usePost()return (<div><h1>文章列表</h1>{isLoading ? <div>加载中</div> :isEmpty ? <div>文章列表为空</div> :posts.map(p => <div key={p.id}>{p.id}</div>)}</div>);};;export default PostsIndex;
完成。
commit:https://github.com/E1FANG/next-blog-1/commit/049c472e5bf1df08816e0318d42e2a62bbba7f31
文章列表完全由前端渲染的,我们称之为客户端渲染。客户端渲染的缺点
- 白屏
- 在AJAX得到响应之前,页面中之后loading
- SEO不友好
- 搜索引擎访问页面,看不到post数据
- 因为搜索引擎默认不执行JS,只能看到HTML
静态内容与动态内容

静态内容:红色部分,直接展示在源代码里面的。是写在代码里面的
动态内容:绿色部分,需要用JS去请求资源,再判断去展示的。是从数据库等地方拉过来的
