【Next服务端渲染学习-SSR】

SSR概念

服务端渲染顾名思义实在服务端渲染dom,css生成页面,相较于客户端渲染,用户不需要再在客户端才请求首屏需要加载资源,首屏加载速度尤其对于C端会有更明显的提升。但同样的项目的复杂性会相较于客户端渲染有所增加,例如需要远程服务器的node服务,从打包构建-到环境部署可能与客户端的纯静态资源上传服务器有所不同,还有在开发难度上与原先的客户端渲染也会有差异。

React下的SSR-Next

在学习的过程中主要关注与客户端渲染是的区别

项目结构

相比于客户端渲染,Next在编写时最大的区别就是目录即路由的概念,项目中不再需要配置routes,也不需要编写嵌套路由的硬性布局。

[your-project-name]
    ├── app
    │   ├── login
    │   │   ├── page.tsx (/login打开的页面)
    │   │   └── layout.tsx (/login页面布局)(可选)
    │   ├── user
    │   │   ├── page.tsx (/user打开的页面)
    │   │   └── layout.tsx (/user页面布局)(可选)
    │   └── api
    │       ├── login 
    │       │   └── route.ts (/api/login)
    │       └── user 
    │           └── route.ts (/api/user)
    ├── layout.tsx (根布局,需要html body)
    └── page.tsx (/打开的页面)

不再需要入口html文件,而是在最顶层的layout.tsx文件当中显示添加html和body
在这里插入图片描述

Next以use client来区分服务端渲染文件还是客户端渲染文件,以use server定义服务端函数

官网文档

  1. 使用浏览器api,或者dom事件,或者像客户端渲染时所用的useState,useEffect需要写入在客户端组件当中(也就是说这部分的内容逻辑必须要单独起一个文件来写,不能一个文件写到底了)
  2. 客户端组件可以作为服务端组件的子组件,服务端父组件可以通过props将值传递给客户端子组件。但是服务端组件不能显示的作为客户端的子组件,只能以children的方式传递到客户端组件中,并且无法传递值给服务端子组件。(原因:use client会使得当前文件以及导入的依赖文件都命中客户端渲染逻辑,从而导致服务端组件不能正常在服务端执行。)
  3. 服务端函数顾名思义是在服务端渲染的函数,在这样子的函数中执行请求,可享受不受跨域影响的请求调用。(客户端组件中也可以使用这个函数,但本质上是next发起了一次请求到服务端,服务端再执行这个函数再将结果进行返回,与rpc通信比较像)

动态路由、路由组、路由插槽、路由拦[Next实现的有别于客户端渲染的]

动态路由、路由组、路由拦截均可按照Next定义的文件夹命名规则来进行实现。

[your-project-name]
    └── app
        ├── (card) (购物车路由组,这层的文件名称不会作为路由path部分)
        │   ├── info
        │   │   ├── page.tsx
        │   │   └── layout.tsx
        │   ├── buy
        │   │   ├── page.tsx
        │   │   └── layout.tsx
        │   └── product
        │       └── [id] (动态路由,等价于客户端渲染的/product/:id路由写法)
        │           ├── page.tsx
        │           └── layout.tsx
        ├── page.tsx
        └── layout.tsx

Next中动态路由官网文档

写法匹配路由入参
[id]/product/1(只能匹配一位不能没有){ slug: 1 }
[…id]/product/1, /product/1/2(可匹配多位不能没有){ slug: [1] },{ slug: [1, 2] }
[[…id]]/product,/product/1,/product/1/2(可匹配多位也能没有){ slug: undefined },{ slug:[1] },{ slug: [1, 2] }

Next中路由插槽官方文档
路由插槽是Next中实现并行路由的方式,可以在一个页面布局中同时渲染多个独立的路由区域
文件夹命令以@开头,在layout文件中作为属性传入
在这里插入图片描述
刷新时需要加载路由插槽的default.tsx文件,如果没有的话Next会渲染出一个404页面。路由插槽的一级文件不必有page和layout文件,因为路由插槽的文件命名不会参与路由路径的组成,当插槽路由匹配不到对应的路由的时候就会默认渲染一个default,所以正常default返回null即可。
Next中路由拦截官方文档
路由拦截是Next基于文件系统自己实现的一种功能,其效果是路由切换后实现页面覆盖效果而非切换不同的上下文。

写法文件层级
(.)与需要拦截的目标路由处于同一个层级
(…)比需要拦截的目标路由低一个层级
(…)(…)比需要拦截的目标路由低两个层级
(…)全局拦截

官方的解释有点抽象。我个人的理解是首先要根据路由加载的链路,未在加载范围内的路由配置的拦截不会生效。
下面的目录结构中根目录有一个@modal,test目录中也存在一个@modal。
app/@modal/(.)phone路由拦截会拦截同一层级【与注入modal插槽路由的layout同层级的路由文件,即/phone/:id】。
当我们打开/test/intercept 这个路由路径的时候,test下的layout会加载test下的@modal插槽。此时又存在了两个路由拦截,app/test/@modal/(.)phone 和app/test/@modal/(…)phone。前者拦截同一层级的路由【与注入modal插槽路由的layout同层级的路由文件,即/test/phone/:id】;后者可以比需要拦截的目标路由文件低一个文件夹层级【反过来说就是可以拦截加载modal的layout上一个层级的路由,即/phone/:id

[your-project-name]
    └── app
        ├── phone
        │   └── [id]
        │       └── page.tsx
        ├── @modal
        │   └── (.)phone
        │       └── [id]
        │           └── page.tsx
        ├── test
        │   ├── @modal
        │   │   ├── (.)phone
        │   │   │   └── [id]
        │   │   │       └── page.tsx
        │   │   └── (..)phone
        │   │       └── [id]
        │   │           └── page.tsx
        │   ├── intercept (/test/intercept 跳转 /test/phone/:id 和 /phone/:id 路由页面)
        │   │   └── page.tsx
        │   ├── phone
        │   │   ├── [id]
        │   │   └── page.tsx
        │   └── layout.tsx (modal 插槽布局)
        └── layout.tsx (modal 插槽布局)

结合上面的项目目录可以看到 intercept中跳转 /test/phone/:id 会被 /test/@modal/(.)phone拦截到。而跳转/phone/:id 则会被 两个拦截规则拦截到,即/@modal/(.)phone和/test/@modal/(…)phone。目前我的理解是根据目标路由的最近原则进行匹配,来从外到内的查找拦截路由。
第一组存在app/@modal/(.)phone拦截规则的时候
在这里插入图片描述
第二组不存在app/@modal/(.)phone拦截规则的时候
在这里插入图片描述
在这里插入图片描述

路由拦截和路由插槽组合使用构成模态框。效果就是软导航(Link)的时候会在当前页面加载一个路由插槽,插槽中的内容是路由拦截文件渲染的内容。但是硬导航(刷新页面)会展示未被拦截的页面内容,一个完整的路由页面

[your-project-name]
    └── app
        ├── @model (路由插槽)└── (.)photo (路由拦截)
        │       ├── [id] (动态路由)
        │       │   └── page.tsx
        │       └── default.tsx
        ├── photo
        │   └── [id] (动态路由)
        │       └── page.tsx
        ├── layout.tsx (model插入布局中)
        └── page.tsx

下面是软访问和硬访问的两种页面效果
软访问是点击红色区域的数字触发的router.push的跳转。硬访问是直接刷新浏览器页面。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值