react课程26-页面建立及Data处理
Last updated on October 18, 2024 pm
本节课包含项目分析、页面建立(包含加载和错误界面)、渲染方面的处理和cache问题。
一、信息
(1)项目分析
(2)suspense
在 React 中,Suspense
是一个用于管理异步操作(例如组件加载或数据获取)的机制。它允许你在组件渲染之前显示一个 “loading” 状态,直到所需的资源加载完毕。Suspense
主要用于处理动态导入的组件或与 React 的 Concurrent Mode 结合使用。
1 |
|
**React.lazy()
**:这是 React 提供的一个方法,用于懒加载组件。它返回一个动态导入的 Promise,直到这个 Promise 解析后,组件才会被渲染。
**Suspense
**:Suspense
包裹着懒加载的组件,负责在组件加载过程中显示一个 “占位符”(通常是一个 loading 状态)。一旦组件加载完成,它就会正常渲染。
fallback
属性:这是 Suspense
的关键属性,用来指定加载过程中要显示的内容。在上例中,当 LazyComponent
正在加载时,浏览器会先显示 <div>Loading...</div>
,直到组件加载完成。
注意:
只用于客户端渲染:Suspense
目前主要用于客户端渲染,而不是在服务器端渲染(SSR)中。
结合数据加载(实验性):Suspense
的最大潜力是与 Concurrent Mode
结合,控制数据加载过程中的用户体验,但这部分功能还处于实验阶段。
(3)Dynamic Route Segment
我们需要为每个小屋创建一个url,总不能为每个id新建一个文件夹吧。
在 Next.js 中,动态路由段(dynamic route segment)是一种用于创建根据 URL 变化而生成不同页面的路由机制。它允许你在文件系统路由中定义一个动态的部分,这样页面路径可以根据参数动态变化。
特点
- 文件名决定路由:文件系统会自动基于文件名生成相应的路由。
- 动态参数:方括号内的内容会被当作动态参数,
useRouter()
钩子可以读取这些参数。 - 嵌套动态路由:你可以在不同层级嵌套动态路由,创建复杂的 URL 结构。
如何使用:
(4)专业术语们
1、Serverless computing
无服务器计算是一种云计算模型,开发人员无需管理服务器,而是专注于编写和部署代码。背后的基础设施由云提供商自动管理,它根据需求动态分配资源并仅在代码运行时计费。尽管名称中包含“serverless”,实际上服务器仍然存在,只是由云提供商负责维护,开发者不必直接接触。
2、ISR:
增量静态再生(Incremental Static Regeneration,简称 ISR)是 Next.js 的一种功能,它允许你在保持静态生成的性能优势的同时,对某些页面进行更新。使用 ISR,可以在不重新构建整个站点的情况下,更新特定页面的内容。这种方式特别适合于内容经常变化但又不需要实时更新的页面,如博客文章、产品列表或新闻网站。
在用户请求某个页面时,如果页面的缓存过期(超过 revalidate
设置的时间),Next.js 会在后台生成一个新的页面副本并将其缓存。用户会立即获得之前缓存的页面,而新的副本会在下一次请求时提供。页面更新后的内容会在下一次用户访问时可见,从而实现内容的增量更新。
二、项目构建起步
app文件夹下创建不想要自动创建路径的文件夹,需要在命名前加”_”。
tailwind.config.js文件夹中找到theme-extend目录,可以在里面添加自定义主题。
⭕npm i @heroicons/react
安装图标库
(1)修建网站布局
1、建立metadata
1 |
|
2、icon
浏览器上方标题旁边的图标,只需要把图片放置在app文件夹根路径中,命名为icon,就设置好了
3、font
Next.js 提供了对自定义字体的强大支持,可以通过
@next/font
动态加载 Google Fonts 或本地字体,不再需要手动从 CDN 引入字体文件。(隐私+性能)
在 CSS 中,
antialiased
通常用来处理字体的渲染方式,主要作用是让字体显示得更加清晰和平滑
导入字体函数:
import { Josefin_Sans } from 'next/font/google';
进行字体配置:
1 |
|
- 运用字体设置:
className={``${josefin.className}``}
4、图像优化
⭕import Image from 'next/image';
方法一:<Image src="/logo.png" height="60" width="60" alt="The Wild Oasis logo" />
(必须指定高度和宽度,否则会报错)
方法二:(静态导入)先导入图像,再直接放置进组件里,接入导入后名字叫logo:
<Image src="logo" quality={10} alt="The Wild Oasis logo" />
(无需设置高度和宽度,quality越高图像质量越高越清晰,大小越大)
fill(填充),placeholder:blur(模糊加载)
- 自动图像优化
Next.js 会自动根据设备的分辨率、视窗大小和图像的具体需求对图像进行优化。它会生成不同尺寸的图像并根据设备加载合适的版本,这样可以减少不必要的资源浪费和页面加载时间。
- 延迟加载(Lazy Loading)
默认情况下,next/image
使用延迟加载技术(lazy loading),只有当图像滚动到视口中时才会进行加载。这可以减少首屏加载时间,提高用户体验。
- 响应式图像处理
next/image
支持自动生成不同尺寸的响应式图像。当你指定图像宽度和高度时,Next.js 会为不同的屏幕大小和分辨率生成合适的图像版本,确保图像在各种设备上都能高效加载。
- 现代图像格式支持
Next.js 会自动为支持的浏览器提供现代化的图像格式(如 WebP)。WebP 图像格式比传统的 JPEG 和 PNG 更加高效,能大幅减少图像的文件大小,提高加载速度。
- 图像裁剪和调整
Next.js 允许对图像进行动态裁剪、缩放和调整大小。例如,你可以为不同的屏幕设置不同的宽度和高度,Next.js 会自动处理这些操作。
- 图像缓存
Next.js 的图像优化功能支持缓存优化后的图像。优化后的图像会被存储在服务器或 CDN 中,确保在后续的页面加载中更快地提供这些图像,从而减少对服务器的请求负担。
- 兼容性处理
Next.js 会根据用户的浏览器特性自动加载最合适的图像格式,并提供最佳的显示效果。例如,对于支持 WebP 的浏览器,Next.js 会提供 WebP 格式图像,而对于不支持的浏览器,会提供 JPEG 或 PNG 格式。
- 减少带宽和流量消耗
通过加载更小、优化后的图像,Next.js 帮助大幅减少带宽消耗,尤其在移动端网络速度较慢的情况下,这对提高用户体验有很大帮助。
5、如何使Image非静态导入图像动态大小
1 |
|
- 指定父类容器
relative
:这表示父容器采用了相对定位(position: relative
),这是 next/image
中使用 layout="fill"
时的必需条件。这样图像才能根据父容器的大小进行定位和调整。
aspect-square
:这通常是一个 Tailwind CSS 的类,表示容器的宽高比为1:1,也就是一个正方形。通过这个类,父容器将被强制保持宽度与高度相等。
col-span-2
:这是典型的网格布局类,表示这个 div
占据了网格中的 2 列宽度。这通常用于 grid
布局中来控制元素的宽度。
- 设置图像格式
layout="fill"
:这是 next/image
组件的一个属性,表示图像将填充整个父容器的空间。由于父容器已经通过 relative
定位并设置了宽高比(正方形),图像将按照父容器的大小动态调整。无需指定图像的宽度和高度,Next.js 会自动计算和优化。
className="object-cover"
:这是一个 CSS 类,通常与 Tailwind CSS 一起使用。object-cover
的作用是让图像保持其原始比例并填满整个容器。如果图像的比例和容器不匹配,它将裁剪图像的一部分,而不是拉伸或压缩图像,从而保持图像的完整性。
6、嵌套layout
我们在app文件夹下放至了layout,但是在文件夹下的account路径下也需要layout布局,那么可以直接在此文件夹中创建layout.js,放置相应的navigation组件即可。
(2)连接supabse
1、根目录下新建.env.local
文件夹
这个文件夹负责放置supabase的URL和KEY。
服务器端变量:例如数据库连接信息、API 密钥等敏感信息放在 .env.local
中,并且不加 NEXT_PUBLIC_
前缀。
客户端变量:如果你需要某些环境变量在浏览器中使用(如公共 API 的 URL),可以加上 NEXT_PUBLIC_
前缀。
URL还是正常的URL,而KEY不用settings->API->Project API keys->(anon public)的key,而是(service_role)中的KEY。(为了绕过RLP)
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️无语了我亲爱的环境变量配置⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
SUPABASE_URL=https://mmyxdnpmmlqmyjxjypmw.supabase.co
SUPABASE_KEY=service_role
🚫不能有空格、🚫没有引号、🚫后面不能加分号。。。🚫字母大小写别写错
我说怎么一直连接不上。。。GPT你真的有毛病一开始不跟我说问了一个小时了才说。。。
2、lib文件夹下建立supabase.js
1 |
|
三、Data处理
现在获取data变得非常方便,仅仅是把RSC设置成async方程,然后直接:
const cabins = await getCabins();
类似这样就可以了。
(1)准备工作
1、允许加载远程图像
我们在调取cabins的数据的时候,会加载supabase上的cabin图像,因此在 Next.js 中配置 remotePatterns
的目的是为了允许应用加载来自特定远程服务器的图像。通过指定 protocol
、hostname
、port
和 pathname
,可以控制哪些外部图像源被允许在的应用中使用。
1 |
|
2、利用suspense使旋转器只放置在需要加载的组件
suspense只能包裹一个组件来使用
在加载cabins界面的时候,如果正在加载cabins数据,整个界面都会被Spinner组件遮挡,包括一部分静态文字,这样会导致bad UX。所以我们可以把获取cabins和渲染cabins的部分提取到一个组件中,然后导入到cabins界面,用suspense包裹住,就🆗了。这里suspense的fallback组件会覆盖cabins界面本身设置的loading组件。
3、Cabin 组件
在Cabins界面时,每个cabin有一个按钮,点击进入详细界面,url设置为cabin/${id}
我们在cabins文件夹下建立[cabinId]
动态文件夹。里面建立page.js就是相应的cabin界面。
让Page组件接收{params}
作为参数, const cabin = await getCabin(params.cabinId);
就可以获得cabin数据。
4、动态metadata
我们想要给cabin界面也设置浏览器标题,同时标题中含有cabin id,于是可以使用函数来动态创建。
1 |
|
5、设置Error Bundaries
与之前的错误边界处理方式不同,在这里我们只需要在app的根目录下创建一个文件夹:error.js
,然后返回一个组件,接收error、reset函数。于是就可以在界面上显示error.message,并且设置按钮,click函数为reset。
⚠️需要声明“use client”
6、not-found error
在app的根目录下创建一个文件夹:not-found.js
,填写相应内容即可,当用户访问不存在的URL的时候就会进入这个界面。
但是我们想要在用户试图访问不存在的id的cabin界面时也进入这个错误界面(默认是显示上面的error界面),于是我们可以找到service文件中的getCabin函数,在error下,调用notFound();
。
我们还想要动态定义cabin下not-found界面的信息,于是可以在[cabinId]文件夹下也创建一个not-found文件夹,写入想要的信息即可。
(2)Data Rendering的两种方式
⭕npm run build
打包后可以在最下方看到哪些文件是静态渲染,哪些是动态
此处[cabinId]
界面是动态渲染,因为nextjs并不知道究竟有多少id
(3)Dynamic->Static
1、如何让next.js知道动态URL段的所有可能值
由于静态界面性能好、更安全等特性,我们想要把动态界面也渲染成静态界面。cabins是有限长度,也很好传递各个id。
1 |
|
generateStaticParams
是 Next.js 中用于 静态生成动态路由参数 的函数。该函数主要用于在构建时生成页面的路径参数,使得这些路径能够在静态站点生成时创建对应的静态页面。其返回的数组会被 Next.js 用来生成静态页面。对于每个 cabinId
,Next.js 会生成对应的静态页面。
2、SSG
SSG(Static Site Generation) 是 Next.js 中的一种渲染方法,允许在构建时生成页面的 HTML,而不是在每次用户请求时动态生成。这种方法可以显著提高页面的加载速度和性能,因为静态页面可以通过 CDN 缓存并在全球范围内快速提供给用户。
由于上面的操作,使得整个APP都是静态渲染,于是可以在next.config.js
文件中配置: output:”export“
,然后运行npm run build,会生成一个out包。使用vscdode打开整个包,下载以下插件之后,会在编译器右下角看到go Live,点击后会生成静态界面。
但是界面中使用Image组件的所有图片都无法被渲染了。因为**next/image
依赖服务端功能**,Image
组件依赖 Next.js 的内置图像优化功能,这在静态导出时并不可用。默认情况下,next export
不支持自动优化图像。
解决问题可以使用Cloudinary图像优化:搜索next.js static export 找到Image Optimization部分,里面有较为详细的配置信息。
3、Patial Pre-Rendering (PPR)
四、Caching in Next.js
(1)概念
1、相同的url和options
2、可以是不同user
no-store
是一种缓存控制指令,指示浏览器和任何中间缓存(如代理服务器)都不应缓存响应。每次请求时,客户端都会向服务器请求新鲜的数据,而不是使用任何先前的缓存内容。unstable_noStore
是 Next.js 中的一个实验性特性,旨在为某些请求提供更细粒度的缓存控制。它允许你在服务器端返回响应时,指定某些内容不应被缓存。这与普通的 noStore
方法类似,但由于它是实验性特性,因此可能在未来的版本中发生变化或被替换。
避免缓存:当你希望确保某些 API 响应或页面请求不被缓存时,可以使用 unstable_noStore
。这对于处理动态内容、实时数据或敏感信息尤为重要。
开发和调试:在开发期间,使用 unstable_noStore
可以确保你始终获得最新的数据或页面渲染,避免缓存引起的混淆。
API 请求:在发送 API 请求时,如果你希望强制获取新数据而不是从缓存中读取,可以在请求配置中使用 unstable_noStore
。
(2)模拟生产环境的caching 和ISR
在package.json 中加入”prod”: “next build && next start” 然后终端输入npm run prod就可以模拟生产环境了。
⚠ For production Image Optimization with Next.js, the optional ‘sharp’ package is strongly recommended. Run ‘npm i sharp’, and Next.js will use it automatically for Image Optimization.(终端的警告)
1、关闭data cache
如果这时候在数据库修改某个值,是不会在网页上显示的,就算刷新也不行,因为这是一个完全静态的界面,所以我们想要关掉data cache(同时也能关掉full route cache)
在cabins的page代码中设置:export const revalidate = 0;
(每次修改都需要重新run)
2、ISR
只需要修改上面的值为我们想要自动刷新的间隔就可。注意时间的单位是秒。
3、noStore
import { unstable_noStore } from 'next/cache';