当前位置:首页 > 科技  > 软件

怎么理解 React Server Component 和 Next.js 的关系

来源: 责编: 时间:2023-11-16 09:39:45 187观看
导读大家好,我卡颂。最近Next.js v14发布,发布会的各种梗图刷爆了国外前端社区。Next.js的诸多特性(比如Server Action、App Router),都是在RSC(React Server Component)基础上衍生出的。从名字可以看出,RSC是React的特性。那么,该

gH728资讯网——每日最新资讯28at.com

大家好,我卡颂。gH728资讯网——每日最新资讯28at.com

最近Next.js v14发布,发布会的各种梗图刷爆了国外前端社区。gH728资讯网——每日最新资讯28at.com

gH728资讯网——每日最新资讯28at.com

Next.js的诸多特性(比如Server Action、App Router),都是在RSC(React Server Component)基础上衍生出的。gH728资讯网——每日最新资讯28at.com

从名字可以看出,RSC是React的特性。那么,该怎么理解RSC和Next.js的关系呢?gH728资讯网——每日最新资讯28at.com

React团队的宿愿

对于前端框架的开发范式,有三个重要衡量因素:gH728资讯网——每日最新资讯28at.com

  • 用户体验
  • 维护成本
  • 性能

但是,通常很难做到三者兼顾(具体原因本文不细究,感兴趣的同学可以看data-fetching-with-react-server-components[1]。gH728资讯网——每日最新资讯28at.com

简单来说,在前端开发中,「IO瓶颈」是影响内容渲染速度的重要因素(可以简单理解为,前端需要等待请求返回数据后,再根据数据渲染内容,这期间延迟的时间就是「IO瓶颈」)。gH728资讯网——每日最新资讯28at.com

但是,前端框架能够掌控的范围局限在前端,所以无法对「IO瓶颈」做出极致优化,只能在三个因素中做出取舍(比如考虑用户体验与性能时,代码维护成本就高)。gH728资讯网——每日最新资讯28at.com

React团队为了同时兼顾三者,需要对服务端拥有更多掌控。这就是RSC诞生的初衷。gH728资讯网——每日最新资讯28at.com

但是,大部分React的受众只是把React当作前端view库,并不会直接使用RSC相关功能,所以React团队选择和Next.js团队合作,落地RSC。gH728资讯网——每日最新资讯28at.com

此时我们发现,React有三类受众:gH728资讯网——每日最新资讯28at.com

  1. 普通前端开发者,用稳定的React做业务开发
  2. 其他合作团队(比如Next.js团队),React团队为他们提供API支持
  3. 喜欢尝鲜的开发者/团队,愿意尝试那些可能出现在未来版本中的特性(通常还不稳定)

React团队针对这三类受众,制定了三条版本迭代路径:gH728资讯网——每日最新资讯28at.com

  • Latest路径
  • Canary路径
  1. Experimental路径

我们正常通过npm i react下载的React包就是「Latest路径」的打包产物。gH728资讯网——每日最新资讯28at.com

通过npm update react@canary可以替换为canary包,RSC相关的功能就属于canary包。gH728资讯网——每日最新资讯28at.com

gH728资讯网——每日最新资讯28at.com

同理,通过npm update react@xperimental可以替换experimental包。gH728资讯网——每日最新资讯28at.com

脱离Next.js使用RSC

在Next.js的App Router模式,所有组件默认为服务端组件(即在服务端render的组件),只有当组件所在文件顶部标记了'use client'指令时,该组件是客户端组件(即在前端render的组件)。gH728资讯网——每日最新资讯28at.com

gH728资讯网——每日最新资讯28at.com

比如下面就是个客户端组件:gH728资讯网——每日最新资讯28at.com

'use client'import {useState} from 'react';function Cpn() {  const [num, update] = useState(0);  // ...省略}

实际上,这并不是Next.js自己的定义,而是RSC中的规范。在React文档中,我们可以看到'use client'与'use server'规范的定义,其中:gH728资讯网——每日最新资讯28at.com

  • 'use client'用于标记客户端组件(在服务端,默认所有组件都是服务端组件,所以客户端组件需要专门标记)。
  • 'use server'用于标记前端的某个函数为Server Action(可以在前端执行的服务端逻辑)。

gH728资讯网——每日最新资讯28at.com

既然是规范,那就需要落地。在Next.js中,规范的落地都被收敛到Next.js框架内部实现了。如果要脱离Next.js使用RSC,就需要我们自己落地规范。gH728资讯网——每日最新资讯28at.com

RSC规范的落地包括三部分:gH728资讯网——每日最新资讯28at.com

  • 服务端编译时
  • 服务端运行时
  • 客户端运行时

这三者都被收敛到react-server-dom-webpack[2]包中。gH728资讯网——每日最新资讯28at.com

接下来我们简单讲下这三部分的作用。gH728资讯网——每日最新资讯28at.com

服务端编译时

通过react-server-dom-webpack/plugin名字中的webpack、plugin字样能看出,这是个webpack插件,配置类似如下:gH728资讯网——每日最新资讯28at.com

const ReactServerWebpackPlugin = require("react-server-dom-webpack/plugin");const config = {  // ...省略其他配置  plugins: [    new ReactServerWebpackPlugin({ isServer: false }),  ],}

他的作用是识别项目中的'use client'指令,作用有些类似于「全自动React.lazy」。gH728资讯网——每日最新资讯28at.com

使用过React.lazy特性的同学会知道,当我们通过React.lazy懒加载组件时,懒加载的组件会被打包工具(比如webpack)打包成独立的chunk。当前端需要该组件时,会通过Jsonp请求chunk文件。gH728资讯网——每日最新资讯28at.com

比如下面代码中的./Cpn.jsx组件由于懒加载,会被打包成独立的chunk:gH728资讯网——每日最新资讯28at.com

import React from 'react';const LayCpn = React.lazy(() => import('./Cpn.jsx'));function App(props) {  return <LayCpn {...props} />; }

与React.lazy类似,当我们在组件所在文件的顶部标记'use client'时,并在服务端组件的子孙组件中使用到该组件,该组件代码也会打包成独立的chunk。由于这个过程是全自动的,所以可以称为「全自动React.lazy」。gH728资讯网——每日最新资讯28at.com

服务端运行时

上面讲到的编译产物都是「客户端组件对应chunk」,所以他们是不会在服务端运行时使用的。gH728资讯网——每日最新资讯28at.com

服务端运行时的作用类似SSR,都是给定JSX输入,经过render后获得输出。比如,给定如下输入:gH728资讯网——每日最新资讯28at.com

function App() {  return <div>hello</div>;}

对于SSR,会获得字符串'<div>hello</div>'的输出。gH728资讯网——每日最新资讯28at.com

对于RSC规范,将输入传给react-server-dom-webpack/server导出的renderToPipeableStream方法,会获得如下序列化数据:gH728资讯网——每日最新资讯28at.com

0:"$L1"1:["$","div",null,{"children":"hello"}]

再让我们看一个稍微复杂点的例子:gH728资讯网——每日最新资讯28at.com

我们有个组件Cpn,由于他包含客户端状态(使用了useState),所以只能作为客户端组件(顶部标记'use client'):gH728资讯网——每日最新资讯28at.com

'use client'import {useState} from 'react';function Cpn() {  const [num, update] = useState(0);  // ...省略}

现在,我们的服务端组件App返回值中包含了Cpn:gH728资讯网——每日最新资讯28at.com

function App() {  return <div><Cpn/></div>;}

经由renderToPipeableStream方法,会获得如下序列化数据:gH728资讯网——每日最新资讯28at.com

0:"$L1"2:I["./src/app/Test.jsx",["client0","client0.chunk.js"],"Test"]1:["$","div",null,{"children":["$","$L2",null,{}]}]

可以发现,序列化数据中并不包含具体的客户端组件代码,而是组件代码对应的文件(client0.chunk.js),这个文件就是我们在「服务端编译时」打包产生的chunk文件。gH728资讯网——每日最新资讯28at.com

客户端运行时

当「服务端运行时」产生的「序列化数据」传递给前端时,react-server-dom-webpack又出场了,这次使用的是react-server-dom-webpack/client。gH728资讯网——每日最新资讯28at.com

这个包提供了几个方法,用于将「从不同数据源获取的序列化数据」转换为「合法的React Element」,比如:gH728资讯网——每日最新资讯28at.com

  • createFromFetch:通过fetch方法获取序列化数据。
  • createFromReadableStream:通过可读流获取序列化数据。

对于上述序列化数据:gH728资讯网——每日最新资讯28at.com

0:"$L1"2:I["./src/app/Test.jsx",["client0","client0.chunk.js"],"Test"]1:["$","div",null,{"children":["$","$L2",null,{}]}]

经由react-server-dom-webpack/client中方法的转换,会得到一个React.lazy组件,这样前端的React就能正常render这个组件了。gH728资讯网——每日最新资讯28at.com

总结

RSC规范属于React特性,来自于React Canary。规范的落地可以通过react-server-dom-webpack包实现。gH728资讯网——每日最新资讯28at.com

整个工作流程包括三个阶段:gH728资讯网——每日最新资讯28at.com

  • 服务端编译时,对应react-server-dom-webpack/plugin。
  • 服务端运行时,对应react-server-dom-webpack/server。
  1. 客户端运行时,对应react-server-dom-webpack/client。

在Next.js中,RSC规范的落地被集成到框架内部,做到了开箱即用的RSC,并在此基础上衍生出更完善的功能(App Router)。gH728资讯网——每日最新资讯28at.com

参考资料

[1]data-fetching-with-react-server-components:https://legacy.reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html。gH728资讯网——每日最新资讯28at.com

[2]react-server-dom-webpack:https://www.npmjs.com/package/react-server-dom-webpack。gH728资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-26561-0.html怎么理解 React Server Component 和 Next.js 的关系

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Java11 的 G1 垃圾收集器

下一篇: TypeScript 5.3 来了,一大波新特性

标签:
  • 热门焦点
  • Redmi Pad评测:红米充满野心的一次尝试

    Redmi Pad评测:红米充满野心的一次尝试

    从Note系列到K系列,从蓝牙耳机到笔记本电脑,红米不知不觉之间也已经形成了自己颇有竞争力的产品体系,在中端和次旗舰市场上甚至要比小米新机的表现来得更好,正所谓“大丈夫生居
  • 0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    旭日森林无糖仙草乌龙茶510ml*15瓶平时要卖为79.9元,今日下单领取50元优惠券,到手价为29.9元。产品规格:0糖0卡0脂,添加草本仙草汁,清凉爽口,富含茶多酚,保留
  • 三言两语说透设计模式的艺术-单例模式

    三言两语说透设计模式的艺术-单例模式

    写在前面单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少
  • 之家push系统迭代之路

    之家push系统迭代之路

    前言在这个信息爆炸的互联网时代,能够及时准确获取信息是当今社会要解决的关键问题之一。随着之家用户体量和内容规模的不断增大,传统的靠"主动拉"获取信息的方式已不能满足用
  • JVM优化:实战OutOfMemoryError异常

    JVM优化:实战OutOfMemoryError异常

    一、Java堆溢出堆内存中主要存放对象、数组等,只要不断地创建这些对象,并且保证 GC Roots 到对象之间有可达路径来避免垃 圾收集回收机制清除这些对象,当这些对象所占空间超过
  • 电视息屏休眠仍有网络上传 爱奇艺被质疑“薅消费者羊毛”

    电视息屏休眠仍有网络上传 爱奇艺被质疑“薅消费者羊毛”

    记者丨宁晓敏 见习生丨汗青出品丨鳌头财经(theSankei) 前不久,爱奇艺发布了一份亮眼的一季报,不仅营收和会员营收创造历史最佳表现,其运营利润也连续6个月实现增长。自去年年初
  • 微博大门常打开,迎接海外画师漂洋东渡

    微博大门常打开,迎接海外画师漂洋东渡

    作者:互联网那些事&ldquo;起猛了,我能看得懂日语了&rdquo;。&ldquo;为什么日本人说话我能听懂?&rdquo;&ldquo;中文不像中文,日语不像日语,但是我竟然看懂了&rdquo;&hellip;&hell
  • Android 14发布:首批适配机型公布

    Android 14发布:首批适配机型公布

    5月11日消息,谷歌在今天凌晨举行了I/O大会,本次发布会谷歌带来了自家的AI语言模型PaLM 2、谷歌Pixel Fold折叠屏、谷歌Pixel 7a手机,同时发布了Androi
  • 质感不错!OPPO K11渲染图曝光:旗舰IMX890传感器首次下放

    质感不错!OPPO K11渲染图曝光:旗舰IMX890传感器首次下放

    一直以来,OPPO K系列机型都保持着较为均衡的产品体验,历来都是2K价位的明星机型,去年推出的OPPO K10和OPPO K10 Pro两款机型凭借各自的出色配置,堪称有
Top