- 客户端渲染
- 只在浏览器上执行的渲染
- 用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去请求资源,再判断去展示的。是从数据库等地方拉过来的