当前位置: 首页 > news >正文

React Server Components:重新定义服务端渲染

React Server Components重新定义服务端渲染前言各位前端小伙伴不知道你们有没有遇到过这种情况页面加载时需要等待大量JavaScript下载和执行导致首屏渲染缓慢我曾经开发过一个内容网站首屏加载时间超过5秒。后来我引入了React Server Components首屏加载时间降到了1秒以内什么是Server ComponentsReact Server ComponentsRSC是React团队推出的一种新的组件类型它允许组件在服务器端运行只将渲染结果发送到客户端从而减少客户端JavaScript体积提升首屏加载性能。Server Components工作原理┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 服务器端 │ │ 网络 │ │ 客户端 │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ │ 1. 渲染Server Component│ │ │───────────────────────│ │ │ │ │ │ │ 2. 发送渲染结果(JSON)│ │ │────────────────────────│ │ │ │ │ │ │ 3. 客户端渲染 │ │ │ │─────────────│创建Server Components基本结构// ServerComponent.js async function ServerComponent() { const data await fetchData() return ( div {data.map((item) ( Item key{item.id} item{item} / ))} /div ) } export default ServerComponent客户端组件引用// ClientComponent.js use client import { useState } from react function ClientComponent({ initialValue }) { const [count, setCount] useState(initialValue) return ( div divCount: {count}/div button onClick{() setCount(c c 1)}Increment/button /div ) } export default ClientComponentServer Components vs Client Components特性Server ComponentsClient Components运行位置服务器端客户端状态管理不支持useState/useEffect支持所有hooks数据获取可以直接调用数据库需要通过API获取文件大小不发送到客户端发送到客户端交互性无有在Next.js中使用Server Components页面组件// app/page.js async function HomePage() { const posts await fetchPosts() return ( div h1Welcome to my blog/h1 PostList posts{posts} / /div ) } export default HomePage布局组件// app/layout.js async function RootLayout({ children }) { const user await getUser() return ( html head titleMy App/title /head body Header user{user} / {children} /body /html ) } export default RootLayoutServer Components实战数据获取// app/posts/page.js async function PostsPage() { const posts await fetch(https://api.example.com/posts).then(res res.json()) return ( div h1Posts/h1 ul {posts.map((post) ( li key{post.id} h2{post.title}/h2 p{post.excerpt}/p /li ))} /ul /div ) } export default PostsPage嵌套使用// app/blog/page.js async function BlogPage() { const posts await getPosts() return ( div h1Blog/h1 PostList posts{posts} / /div ) } async function PostList({ posts }) { return ( div {posts.map((post) ( PostCard key{post.id} post{post} / ))} /div ) } async function PostCard({ post }) { const author await getAuthor(post.authorId) return ( div h3{post.title}/h3 pBy {author.name}/p /div ) }混合使用Server和Client Components在Server Component中使用Client Component// app/page.js import ClientCounter from ./ClientCounter async function HomePage() { const initialCount await getInitialCount() return ( div h1Home/h1 ClientCounter initialCount{initialCount} / /div ) } export default HomePage // app/ClientCounter.js use client import { useState } from react function ClientCounter({ initialCount }) { const [count, setCount] useState(initialCount) return ( div divCount: {count}/div button onClick{() setCount(c c 1)}Increment/button /div ) } export default ClientCounter在Client Component中使用Server Component// app/ClientWrapper.js use client import { useState } from react import ServerContent from ./ServerContent function ClientWrapper() { const [isLoaded, setIsLoaded] useState(false) return ( div {isLoaded ? ( ServerContent / ) : ( divLoading.../div )} button onClick{() setIsLoaded(true)}Load Content/button /div ) } export default ClientWrapperServer Components最佳实践1. 将数据获取逻辑放在Server Components中async function ProductList() { const products await fetchProducts() return ( div {products.map((product) ( ProductCard key{product.id} product{product} / ))} /div ) }2. 将交互逻辑放在Client Components中use client function ProductCard({ product }) { const [isFavorite, setIsFavorite] useState(false) return ( div h3{product.name}/h3 button onClick{() setIsFavorite(!isFavorite)} {isFavorite ? ❤️ : } /button /div ) }3. 合理划分组件边界// Server Component - 数据获取 async function BlogPost({ id }) { const post await getPost(id) return ( article h1{post.title}/h1 ContentRenderer content{post.content} / CommentSection postId{id} / /article ) } // Client Component - 交互 use client function CommentSection({ postId }) { const [comments, setComments] useState([]) useEffect(() { fetchComments(postId).then(setComments) }, [postId]) return ( div {comments.map((comment) ( Comment key{comment.id} comment{comment} / ))} /div ) }常见问题问题1Server Component中无法使用hooks解决方案将需要hooks的逻辑移到Client Component中问题2Client Component无法直接获取数据解决方案通过props从Server Component传递数据问题3缓存问题解决方案使用revalidate属性控制缓存策略export const revalidate 60 // 60秒重新验证Server Components的优势减少JavaScript体积Server Components不发送到客户端提升首屏加载服务端渲染更快的首屏展示简化数据获取直接在组件中获取数据更好的SEO完整的HTML输出总结React Server Components是React生态的重要革新。通过使用Server Components我们可以优化性能减少客户端JavaScript体积提升体验更快的首屏加载简化开发直接在组件中获取数据改进SEO完整的服务端渲染现在开始使用Server Components构建更高效的应用吧你的用户会感谢你的最后一句忠告不要将所有组件都改为Server Components根据需求合理选择
http://www.zskr.cn/news/1314313.html

相关文章:

  • 告别漫长等待:优化CMake配置,加速你的OpenSceneGraph 3.6.5编译过程
  • 海外仓WMS价格全解析
  • 【CRC实战】CRC-16 IBM-3740在嵌入式通信协议中的C语言实现与优化
  • C++的四种类型转换
  • 出海运营必备|2026年5款电商图片翻译工具实测对比
  • 【NotebookLM数学研究避坑白皮书】:12类典型失效场景+对应修复公式模板(附NASA喷气推进实验室实测数据)
  • 2026年全球网络安全面临的挑战有那些?
  • Android、iOS实现在线浏览PDF
  • 2026年|论文降AI实战:手把手教你过知网AIGC检测的降AI技巧与高效工具避坑指南 - 降AI实验室
  • NotebookLM+学术期刊投稿(独家内测名单曝光:3本尚未公开但已接受LM生成文献综述的Q1期刊)
  • Godot PCK解包器技术深度解析:从文件格式到资源提取实践
  • Hermes 的核心架构 Harness:上下文、工具、权限与执行控制
  • 图解人工智能(24)机器学习策略-遗传算法
  • 硬件入门 + 单片机基础(第10天)MQTT协议零基础详解
  • 别再怪虚拟机了!Linux 下 ttyUSB0 不出现的 3 个真实原因与排查手册
  • 如何用NotebookLM 72小时内完成一篇SCI级渔业资源评估报告?——中科院黄海水产所团队实测工作流首次公开
  • NotebookLM知识图谱构建:从零到生产级部署的7个关键决策点(含GCP/AWS适配清单)
  • 每月最低9.9元,中国电信推出试商用Token套餐;卢伟冰称部分国产旗舰直板手机价格或将破万;OpenClaw团队晒账单:月烧800多万|极客头条
  • ENVI实战:从分类栅格到专业土地利用专题图
  • JCMsuite应用:斜入射平面波通过孤立狭缝的光传播
  • Nodejs开发者如何通过环境变量与Taotoken快速调用大模型
  • 下位机断电重连后,上位机如何自动恢复通信?
  • 2026服务器租用优质服务商权威推荐:服务器主机租用/服务器存放/服务器托管公司/服务器的租用租赁/服务器租用报价/选择指南 - 优质品牌商家
  • 2026年口碑好的阳极氧化金属铝牌高口碑品牌推荐 - 行业平台推荐
  • 【Python】从‘TypeError: list indices must be integers or slices, not str’出发,掌握列表索引与数据结构的正确打开方式
  • NotebookLM智能分析实战:3步完成数据洞察转化,90%用户忽略的提示工程关键点
  • 产教融合圆桌会议
  • 第一章:项目概述与环境搭建
  • 详解C++编程中类的声明和对象成员的引用
  • C++ STL 常用算法操作实例详解