nextjs渲染篇

1 服务器组件

默认情况下,Next.js 使用服务器组件。

1.1 服务器组件是如何呈现的?

在服务器上,Next.js 使用 React 的 API 来编排渲染。渲染工作被拆分为多个块:按单个路段和Suspense

每个区块分两个步骤呈现:

  1. React 将服务器组件渲染为一种称为 React Server 组件有效负载 (RSC Payload) 的特殊数据格式。
  2. Next.js 使用 RSC 有效负载和客户端组件 JavaScript 指令在服务器上呈现 HTML

然后,在客户端上:

  1. HTML 用于立即显示路由的快速非交互式预览 - 这仅适用于初始页面加载。
  2. React Server 组件有效负载用于协调客户端和服务器组件树,并更新 DOM。
  3. JavaScript 指令用于 hydrate客户端组件,并使应用程序具有交互性。

RSC 有效负载是渲染的 React Server 组件树的紧凑二进制表示。客户端上的 React 使用它来更新浏览器的 DOM。

 1.2 渲染策略

1.2.1 静态渲染(默认)

使用静态渲染时,路由在构建时渲染,或在数据重新验证后在后台渲染。结果被缓存,

1.2.2 动态渲染

当路由包含对用户个性化的数据或具有仅在请求时才能知道的信息(例如 cookie 或 URL 的搜索参数)

在渲染过程中,如果发现动态函数或未缓存的数据请求,Next.js将切换到动态渲染整个路由。下表总结了动态函数和数据缓存如何影响路由是静态呈现还是动态呈现:

动态函数数据路线
缓存静态渲染
是的缓存动态渲染
未缓存动态渲染
是的未缓存动态渲染

注:静态渲染只有在非动态函数和数据缓存同时存在情况 

1.2.3 流式

通过流式处理,可以从服务器逐步呈现 UI。工作被拆分为多个块,并在准备就绪时流式传输到客户端。这允许用户在整个内容完成呈现之前立即看到页面的某些部分。

 例如:

<Suspense fallback={<Loading />}><Albums />
</Suspense>

children:要呈现的实际 UI。

fallback:如果实际 UI 尚未完成加载,则要代替实际 UI 进行渲染的备用 UI 

2 客户端组件

"use client"用于声明服务器和客户端组件模块之间的边界
例如:

'use client'import { useState } from 'react'export default function Counter() {const [count, setCount] = useState(0)return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>)
}

 3 组合模式

何时使用服务器和客户端组件?

3.1 将仅限服务器的代码排除在客户端环境之外

npm install server-only

 然后导入server-only

import 'server-only'export async function getData() {const res = await fetch('https://external-service.com/data', {headers: {authorization: process.env.API_KEY,},})return res.json()
}

 3.2 使用第三方软件包和提供程序

import { Carousel } from 'acme-carousel'export default function Page() {return (<div><p>View pictures</p>{/* Error: `useState` can not be used within Server Components */}<Carousel /></div>)
}

由于三方组件使用了客户端组件,服务器组件不能使用useState

则需要包装一层:

'use client'import { Carousel } from 'acme-carousel'export default Carousel

现在,可以直接在服务器组件中使用:<Carousel />

import Carousel from './carousel'export default function Page() {return (<div><p>View pictures</p>{/*  Works, since Carousel is a Client Component */}<Carousel /></div>)
}

3.3 使用上下文提供程序

上下文提供者通常在应用的根附近渲染,以共享全局关注点,例如当前主题。

(1)错误例子:

import { createContext } from 'react'//  createContext is not supported in Server Components
export const ThemeContext = createContext({})export default function RootLayout({ children }) {return (<html><body><ThemeContext.Provider value="dark">{children}</ThemeContext.Provider></body></html>)
}

(2)正确例子:(由于服务器组件不支持 React 上下文,采用children的方式)

app/theme-provider.tsx

'use client'import { createContext } from 'react'export const ThemeContext = createContext({})export default function ThemeProvider({children,
}: {children: React.ReactNode
}) {return <ThemeContext.Provider value="dark">{children}</ThemeContext.Provider>
}

 app/layout.tsx

import ThemeProvider from './theme-provider'export default function RootLayout({children,
}: {children: React.ReactNode
}) {return (<html><body><ThemeProvider>{children}</ThemeProvider></body></html>)
}

3.4 交错的服务器和客户端组件

不支持的模式:将服务器组件导入客户端组件

'use client'// You cannot import a Server Component into a Client Component.
import ServerComponent from './Server-Component'export default function ClientComponent({children,
}: {children: React.ReactNode
}) {const [count, setCount] = useState(0)return (<><button onClick={() => setCount(count + 1)}>{count}</button><ServerComponent /></>)
}

支持的模式:将服务器组件作为道具传递给客户端组件

'use client'import { useState } from 'react'export default function ClientComponent({children,
}: {children: React.ReactNode
}) {const [count, setCount] = useState(0)return (<><button onClick={() => setCount(count + 1)}>{count}</button>{children}</>)
}

 将服务器组件作为子项导入

// This pattern works:
// You can pass a Server Component as a child or prop of a
// Client Component.
import ClientComponent from './client-component'
import ServerComponent from './server-component'// Pages in Next.js are Server Components by default
export default function Page() {return (<ClientComponent><ServerComponent /></ClientComponent>)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/822909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQLite的PRAGMA 声明(二十三)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite从出生到现在&#xff08;发布历史记录&#xff09;&#xff08;二十二&#xff09; 下一篇&#xff1a;用于 SQLite 的异步 I/O 模块&#xff08;二十四&#xff09; PRAGMA 语句是特定于 SQLite 的 SQL 扩…

Valorant 瓦罗兰特更新后进不去游戏?3个解决方法完美解决

Valorant 瓦罗兰特更新后进不去游戏&#xff1f;3个解决方法完美解决 《无畏契约&#xff08;VALORANT&#xff09;》是一款由知名游戏开发商&#xff08;Riot Games&#xff09;开发并且免费的多人射击游戏。游戏背景设定在一个幻想世界中&#xff0c;玩家将探索瓦罗兰大陆上…

基于python的二手房数据分析建模及可视化研究,爬取链家二手房数据,可视化分析,房价预测模型

介绍 主要涉及通过爬取济南市链家二手房数据&#xff0c;然后对数据进行处理&#xff0c;包括缺省值处理&#xff0c;高德地图获取二手房地址所属市区&#xff0c;经纬度等数据处理。然后通过python的flask框架编写后端接口&#xff0c;把数据响应给前端。然后前端通过AJAX请求…

谈谈微前端

相关问题 为什么要用微前端微前端的优缺点 回答关键点 独立开发 独立运行 独立部署 自治 微前端是一种架构理念&#xff0c;它将较大的前端应用拆分为若干个可以独立交付的前端应用。这样的好处是每个应用大小及复杂度相对可控。在合理拆分应用的前提下&#xff0c;微前端能…

【Java基础学习】面向对象编程

开始时间: April 10, 2024 结束时间: April 16, 2024 阶段: Done 基础部分 类与对象的关系 类是抽象的&#xff0c;概念的&#xff0c;代表一类事物对象是具体的&#xff0c;实际的&#xff0c;代表一个具体事物&#xff08;实例&#xff09;类是对象的模板&#xff0c;对象…

Python 数学应用(四)

原文&#xff1a;zh.annas-archive.org/md5/123a7612a4e578f6816d36f968cfec22 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十一章&#xff1a;其他主题 在本章中&#xff0c;我们将讨论一些在本书前几章中没有涉及的主题。这些主题大多涉及不同的计算方式以及优…

记录-海思开发板的 嵌入式nginx和 php的移植(交叉编译环境配置)

嵌入式 lnmp搭建的记录 N&#xff1a;NginxP&#xff1a;php编译PHP可能遇到的问题configure阶段&#xff1a;Makefile-make阶段&#xff1a;Makefile-make install阶段&#xff1a; 文章比较水&#xff0c;并没有没解决什么实际问题&#xff0c;有点不好意思发布。但好像又记录…

Python 数据结构和算法实用指南(三)

原文&#xff1a;zh.annas-archive.org/md5/66ae3d5970b9b38c5ad770b42fec806d 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第七章&#xff1a;哈希和符号表 我们之前已经看过数组和列表&#xff0c;其中项目按顺序存储并通过索引号访问。索引号对计算机来说很有效…

安装 k8s集群的问题:默认容器运行时从 Docker 改为 Containerd

安装 k8s集群的问题&#xff1a;默认容器运行时从 Docker 改为 Containerd 1、背景2、容器运行时从 Docker 改为 Containerd2.1、安装 Containerd&#xff1a;2.2、生成 Containerd 的配置文件2.3 、创建 /etc/crictl.yaml 文件2.4 、配置 Containerd 服务开机自启 &#x1f49…

安全认证Kerberos详解

文章目录 一、Kerberos入门与使用1、Kerberos概述1.1 什么是Kerberos1.2 Kerberos术语1.3 Kerberos认证原理 2、Kerberos安装2.1 安装Kerberos相关服务2.2 修改配置文件2.3 其他配置与启动 3、Kerberos使用概述3.1 Kerberos数据库操作3.2 Kerberos认证操作 二、Hadoop Kerberos…

海外仓管理系统的“实用性”讨论:没办法自由设置信息的,都是伪功能

和很多经营海外仓的企业都聊过这样一个问题&#xff1a;对于海外仓的管理系统&#xff0c;到底什么样的设计&#xff0c;什么样的功能才是真的有价值的。 那这就不得不说到一个概念&#xff1a;自由性。什么意思呢&#xff0c;海外仓看似都一样&#xff0c;大家都在经营仓储、…

ppt里的音乐哪里来的?

心血来潮&#xff0c;想照着大神的模板套一个类似于快闪的ppt。 ppt里是有一段音乐的&#xff0c;那段音乐就是从幻灯片第二页开始响起的。 但是我就找不到音乐在哪。 甚至我把ppt里的所有素材都删除了&#xff0c;再看动画窗格&#xff0c;仍然是空无一物&#xff0c;显然&…

研究表明,全球互联网流量竟有一半来自机器人

据Cyber News消息&#xff0c;Thales Imperva Bad Bot近期做了一份报告&#xff0c;显示在2023年有49.6%的互联网流量竟来自机器人&#xff0c;比上一年增长 2%&#xff0c;达到自2013年以来观察到的最高水平。 报告称&#xff0c;这一趋势正对企业组织产生负面影响&#xff0c…

Oracle 正则,开窗,行列转换

1.开窗函数 基本上在查询结果上添加窗口列 1.1 聚合函数开窗 基本格式: ..... 函数() over([partition by 分组列,...][order by 排序列 desc|asc][定位框架]) 1&#xff0c;partition by 字段 相当于group by 字段 起到分组作用2&#xff0c;order by 字段 即根据某个字段…

《教学管理与教育研究》简介及投稿邮箱

《教学管理与教育研究》简介及投稿邮箱 《教学管理与教育研究》是教育部主管、语文出版社主办的国家级教育类学术期刊&#xff0c;本刊面向全国学校教育的发展管理、教学研究、科研创新和师资培养等领域&#xff0c;展示我国学校教育科研领域的最新成果&#xff0c;交流教学管…

Docker安装xxl-job分布式任务调度平台

文章目录 Docker安装xxl-job分布式任务调度平台1.xxl-job介绍2. 初始化“调度数据库”3、docker挂载运行xxl-job容器3.1、在linux的opt目录下创建xxl_job文件夹&#xff0c;并在里面创建logs文件夹和application.properties文件3.2、配置application.properties文件&#xff0c…

基于springboot+vue+Mysql的校园新闻网站

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

分布式锁设计

一、为什么需要分布式锁 1.1 单体项目同步实现 在单进程&#xff08;启动一个jvm&#xff09;的系统中&#xff0c;当存在多个线程可以同时改变某个变量&#xff08;可变共享变量&#xff09;时&#xff0c;就需要对变量或代码块做同步&#xff0c;使其在修改这种变量时能够线…

关于Git的一些基础用法

关于Git的一些基础用法 1. 前言2. 使用GitHub/gitee创建项目2.1 创建账号2.2 创建项目2.3 下载仓库到本地2.4 提交代码到远端仓库2.5 查看日志2.6 同步远端仓库和本地仓库 1. 前言 首先说一个冷知识&#xff08;好像也不是很冷&#xff09;&#xff0c;Linux和git的创始人是同…

客户关系管理(CRM)是什么?CRM 客户关系管理系统完整指南

通过本文&#xff0c;你将了解&#xff1a; CRM是什么样的软件呢&#xff1f; 企业CRM普遍存在哪些难题&#xff1f;又该怎样解决呢&#xff1f; CRM软件有什么样的功能&#xff1f; 未来CRM软件将朝什么方向发展呢&#xff1f; 以我们公司正在使用的CRM系统为例—— 简道云…