ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Next.js vs React 深度对比:渲染模式、路由与全栈能力的选型指南(附 refine 官方示例实证)

Next.js vs React 深度对比:渲染模式、路由与全栈能力的选型指南(附 refine 官方示例实证) Next.js vs React 深度对比渲染模式、路由与全栈能力的选型指南附 refine 官方示例实证【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine本文以 refine 官方博客的《Next.js vs React》对比文章为骨架系统梳理 React 与 Next.js 在渲染模式CSR/SSR/SSG、数据获取与缓存、路由机制、SEO、图片处理、安全特性、后端 API 开发与工程配置上的核心差异并结合本仓库中examples/with-nextjs官方示例与packages/nextjs-router路由包的真实源码验证这些概念在 refine 生态中的落地方式。读完后你将能够根据自身项目形态营销型页面 vs 内部工具/SPA做出有依据的技术选型并了解如何用 refine 将 Next.js 的文件路由能力接入一套 headless 的 React 管理后台框架。一、两者的关系不是竞争而是父子初学者常把 React 和 Next.js 当成一对竞争技术但实际上二者是父子关系Next.js 建立在 React 的组件化基石之上并为其注入了 SSR、SSG、页面级路由与后端 API 等约定驱动的能力。真正有价值的问题不是谁更强而是对新手而言哪一个更简单哪一个更安全约定更强、出错空间更小是否存在替代品使用它们是否要求开发者具备特定专长1.1 什么是 ReactReactReact.js是一个开源 JavaScript 库专注于构建用户界面尤其是单页应用SPA。它的核心能力包括组件化架构在 JavaScript 函数组件中同时编写 HTML 标记与渲染逻辑把应用关注点封装为可复用组件决定页面上 HTML 元素与数据如何呈现Virtual DOMReact 的重要底层技术只智能更新页面中发生变化的部分保证高效快速的渲染这也是客户端渲染CSR模式的理论来源支撑起高性能 SPA 的构建JSXJavaScript XML将 HTML 的熟悉感与 JavaScript 的表达能力结合先在 Virtual DOM 中跟踪并更新页面再把变更后的元素重新注入浏览器文档单向数据流使应用标记、样式与复杂业务逻辑可以仅用 JavaScript 实现让前端应用与各类后端技术的集成更灵活。1.2 什么是 Next.jsNext.js 脱胎于围绕 React 的 SPA 与 CSR 模式所沉淀的经验、创新与约定其标志性贡献包括基于文件的路由把 SPA 之上必需的、资源导向的页面路由与导航问题规范化数据获取与缓存的抽象通过一组函数让 React 组件与页面高效地管理 API 数据服务端渲染SSR让 React SPA 具备静态站点生成SSG能力在构建期与按需时生成静态页面。Next.js 13 之后的版本与 React 团队合作用 React Server Components 实现 SSR由 Server Components 与 Client Components 组合而成的页面可以直接与数据层通信并在客户端获得最新数据后端 API 能力完整支持服务端路由、中间件集成以及通过 ORM如 Prisma连接数据库使 Next.js 成为一个基于 React 的全栈框架。一句话概括任何 React 能做的事情Next.js 都能有效完成并且额外提供了约定化、有主见opinionated的全栈特性。二、核心差异渲染模式渲染行为是 Next.js 与其底层 React 组件基石之间最重要的区分点。React 本身实现 CSRNext.js 在此基础上于其 Rust 语言实现的服务器侧提供架构更完整的 SSR并内建 React 的 CSR 能力。2.1 服务端渲染SSR是什么SSR 是一种模式网站内容在 Web 服务器上生成而非在浏览器中生成。服务器在最初就创建应用的完整 HTML 表示并直接发送给浏览器在良好的网络下只需几毫秒。从浏览器诞生起把 HTML 放上屏幕的已知方法就是 SSR。2004 年 Facebook 刚上线时Web 开发以服务器为中心包括 Facebook 早期版本在内的网站重度依赖 SSR用户每执行一个动作加好友、发状态服务器都会生成新的 HTML 页面并回传浏览器通常导致整页刷新。随着 Web 开发演进客户端渲染CSR概念逐渐流行——不再依赖服务器渲染每一次变化而是利用用户浏览器动态更新内容。2.2 客户端渲染CSR是什么CSR 是在浏览器中使用 JavaScript 动态生成内容的技术。浏览器从服务器获得的是一份骨架式HTML 结构外加 JavaScript 文件由 JS 负责在浏览器内渲染出其余内容。用户会感受到轻微延迟因为浏览器需要先加载 JavaScript。值得注意的是CSR 是相对较新的展示模式它随 React.js 的出现而流行并被 React 纳入其核心开发方式。CSR 的优势想象早期的 Facebook 信息流。若用 SSR每次点赞或评论都需要整页刷新而 CSR 下只有变化的局部如点赞数或评论区更新无需整页重载用户体验更平滑流畅。2.3 CSR 还是 SSR哪个更好取决于具体要实现什么。但就Next.js 与 React 的区别而言渲染模式本身并不是分水岭——因为Next.js 开箱即用地实现了 React 的 CSR并在此之上叠加了 SSR。更关键的是Next.js 允许用两种方式执行 React 的客户端渲染。方式一使用useEffect()Hook 取数适用于一切 React 应用import React, { useState, useEffect } from react; export function Page() { const [data, setData] useState(null); const [error, setError] useState(null); useEffect(() { const fetchData async () { try { const response await fetch(https://api.example.com/data); if (!response.ok) { throw new Error(HTTP error! status: ${response.status}); } const result await response.json(); setData(result); } catch (e) { setError(e); console.error(An error occurred while fetching the data: , e); } }; fetchData(); }, []); if (error) { return pError fetching data: {error.message}/p; } return p{data ? Your data: ${data} : Loading...}/p; }这种做法属于所有 React 应用的通用能力。不过就数据获取场景而言建议使用 React Query 这类专门库以获得更好的性能与开发效率。方式二在 Next.js 页面中用 React Query 以最小化方式取数import React from react; import { useQuery } from react-query; // Function to fetch data const fetchData async () { const response await fetch(https://api.example.com/data); if (!response.ok) { throw new Error(Network response was not ok); } return response.json(); }; function App() { // Using the useQuery hook to fetch data const { data, error, isLoading } useQuery(fetchData, fetchData); if (isLoading) { return pLoading.../p; } if (error) { return pError: {error.message}/p; } return ( div h1Data from API:/h1 ul {data.map((item, index) ( li key{index}{item}/li ))} /ul /div ); } export default App;Next.js 的多重选项为开发者带来明显优势不同于 React.jsNext.js 为开发者提供了组件渲染方式的备选。Next.js 借助名为getServerSideProps的async函数实现 SSR。该函数由服务器在每次请求到达时调用。例如当页面需要预渲染经常更新的数据来自外部 API时可以编写getServerSideProps它取回必要数据并作为 props 供给Page /组件export default function Page({ fetchedData }) { // Use fetchedData for rendering... } // Called on every server-side request export async function getServerSideProps() { // Retrieve data from the external API const response await fetch(https://.../data); if (!response.ok) { throw new Error(Failed to fetch data); } const fetchedData await response.json(); // Supply data to the page through props return { props: { fetchedData } }; }就首屏加载时间而言使用 Next.js 的服务端渲染应用在性能上通常优于纯客户端渲染的 React 应用具体差异取决于多种因素而 SSR 在SEO 与感知加载时间上的收益尤为显著。2.4 静态站点生成SSGSSG 与 SSR 模式紧密相关是 SSR 备受青睐的产物——它在搜索引擎优化SEO页面开发中人气很高因为能提供更快的首屏加载。React 与 Next.js 都提供了 SSG 机制但实现与能力不同。React基础方案React 默认在浏览器中动态渲染内容。要用 React 实现 SSG开发者通常要依赖额外工具与配置——React 并不原生支持 SSG实践中会用 Create React App 配合静态站点生成器来预渲染内容。Next.js增强的 SSG 能力Next.js 把 SSG 提升到更高水平内建静态站点生成支持且开发者体验友好。在 Next.js 中没有使用任何数据获取方法的页面默认会被预渲染为静态 HTML从而优化性能。Next.js 提供getStaticProps函数允许开发者在构建期获取数据并生成静态页面非常适合内容更新不频繁的场景。开发模式下next dev页面按需编译生产构建则把页面预渲染为 HTML 并优化部署终端会输出清晰的日志显示哪些页面正在被静态生成通过next export开发者可以生成可托管在静态站点平台上的完整静态站点。三、数据获取与缓存数据获取与缓存在 Next.js 中的实现方式与其 SSR 的实现方式密切相关。React依赖外部库React 需要外部库来获取后端 API 数据、缓存并管理其状态。纯 React 开发者必须自己确定观点、组件、架构与配置客户端状态管理可用 XState、MobX 或 Redux服务端数据管理则可用 React Query、Redux Toolkit Query 或 SWR。Next.js内置约定相比之下Next.js 提供久经考验且被广泛采用的约定用一组函数在服务端生成静态/动态页面也在客户端渲染动态组件getStaticProps从外部 API 取数填充在服务端于构建期渲染的静态页面getServerSidePropsgetStaticProps的服务端动态等价物用于在每次请求时重新拉取 API 数据以在 SSR 中渲染页面。这与 Next.js 作为 SSR 一部分实现的基于文件的页面路由配合工作。Next.js 13 引入的 App Router带来了开箱即用的服务端数据管理通过扩展fetchWeb API 提供服务端数据获取、缓存与再验证revalidation。Next.js 的数据获取与缓存可在 React Server Components 内的服务端动作Server Actions与变更mutations中使用配合use server指令实现静态与动态页面渲染App Router 的约定则用 Client Components 实现客户端渲染并通过use client指令与 Server Components 组合。仓库实证本仓库的 with-nextjs 示例的数据层 正是这一模式的体现——文件首行声明use client在客户端组件中创建基于refinedev/simple-rest的 dataProvider 并请求 API 地址把取数逻辑放客户端、页面渲染交给框架这一约定落到 refine 的数据层抽象上。四、路由机制对比Next.js 的 SSR 模式与其直觉化的页面级路由约定互为补充。React 本身不为 CSR 提供内建路由但对集成任何开发者选定的库持开放态度。4.1 React自选路由库React 对路由无主见unopinionated。这意味着我们必须依赖某个自选的路由库来实现 SPA 内的导航。主要缺点若所选库不够直觉、不带有 RESTful API 所需的路由约定可能要从零构建整套路由系统主要优点可以自由选择库来建立自己的约定。最流行的选择是 React Router 库它提供一组组件与 Hooks 来定义和管理路由用Route /组件声明路由通常用Link /或NavLink /组件处理导航。import { BrowserRouter as Router, Routes, Route, Link } from react-router-dom; function App() { return ( Router Link to/our-teamOur Team/Link Routes Route path/our-team element{OurTeam /} / /Routes / /Router ); } function OurTeam() { return divWelcome to the Our Team page!/div; }React 中的动态路由React Router 使用:parameter语法实现动态路由。例如为团队成员建立动态路由路径写作/team/:memberIdimport { BrowserRouter as Router, Routes, Route, Link } from react-router-dom; function App() { return ( Router Link to/team/jane-doeJane Does Profile/Link Routes Route path/team/:memberId element{TeamMember /} / /Routes / /Router ); } function TeamMember(props) { return divWelcome to the profile of {props.match.params.memberId}!/div; }4.2 Next.js有主见的基于文件的路由相比之下Next.js 以其页面级路由约定带来了直觉化的简洁与 SSR 模式相辅相成。基于文件的服务端路由让页面开发极其高效。基础页面路由在 Next.js 中src/pages目录不只是一个普通文件夹它是应用服务端路由的心脏。框架最终把这个目录下的文件结构转换为一一映射的页面路由pages |-- OurTeam.tsx - /our-teampages/OurTeam.tsxfunction OurTeam() { return divWelcome to the Our Team page!/div; } export default OurTeam;页面级路由提供了纯 React 开发者在构建 RESTful 页面时常常想要的便利——而 Next.js 开箱即用地提供。动态路由并非所有路由都是静态的。Next.js 用合理的默认值从文件夹结构与作为 props 传入的页面标识符推断动态页面路由。例如构建电商/会员站点动态展示成员详情pages |-- team |-- [memberId].tsx - /team/jane-doe, /team/john-doe, etc.对应代码pages/team/[memberId].tsxfunction TeamMember({ memberId }) { return divWelcome to the profile of {memberId}!/div; } // Fetching the memberId from the route export async function getServerSideProps(context) { return { props: { memberId: context.params.memberId }, }; } export default TeamMember;路由导航Link /组件Next.js 提供自定义Link /组件用户悬停在链接上时它会预取prefetch数据提升应用性能import Link from next/link; function HomePage() { return ( div Welcome to the Home page! Link href/our-teamVisit Our Team/Link /div ); } export default HomePage;这比纯 React Router 的Link /组件更有主见。基于文件的路由这类约定存在潜在锁定lock-in弊端但在我们决定自定义配置、改用其他约定或退回纯 React 从零构建之前Next.js 可以先带我们走很长一段路。总体而言Next.js 提供的正是大多数 React 开发者若被允许从零构建路由时本来就想拥有的东西。仓库实证refine 官方的 with-nextjs 示例 完整展示了这一约定在真实项目中的形态src/app目录下每个资源拥有page.tsx列表、create/page.tsx新建以及带动态段[id]的show与edit路由如 blog-posts 的编辑页与上文team/[memberId].tsx的[参数]动态路由思想完全一致只不过用的是 13 的 App Router 目录约定src/app而非src/pages。refine 通过 packages/nextjs-router 把路由能力接入框架从 入口导出 可以看到 App Router 绑定导出routerProvider默认导出、NavigateToResource、parseTableParams与paramsFromCurrentPath等能力同时该包在src/pages下保留 Pages Router 绑定两种路由体系均可被 refine 的routerProvider消费。在示例的 根布局 中Refine直接接收routerProvider{routerProvider}并在resources中声明list/create/edit/show各页面路径如edit: /blog-posts/edit/:id把资源声明与文件系统路由桥接起来。小结路由篇简洁 vs 灵活Next.js 提供直观的文件式路由开发者无需额外配置即可建立路由React 更灵活但需要手动配置自选库。性能Next.js 的Link /通过页面预取增强性能这是 React 路由不具备的固有特性。学习曲线对初学者Next.js 直觉化的主见式路由更容易上手React 的路由虽然强大但性质上学习曲线可能更陡。五、SEO 考量React 因依赖客户端渲染内容在浏览器中生成而对 SEO 构成挑战搜索引擎未必能正确索引动态加载的内容。Next.js 支持 SSR 与 SSG在服务器端预渲染内容使 Google 等搜索引擎更容易索引页面从而获得更好的 SEO。如果 SEO 很重要Next.js 大概率是更好的选择。六、图片处理React vs Next.js在 React 中处理图片往往需要手工操作自己优化或用第三方工具做懒加载、缩放。Next.js 用内建Image /组件简化这一切自动优化图片包括针对不同设备的懒加载与缩放import Image from next/image; const MyComponent () ( Image src/path/to/image.jpg altDescription of image width{500} height{500} / );其余工作由 Next.js 完成使其成为图片密集型网站的理想选择。七、安全特性Next.js vs ReactReact 只是前端库安全方面认证与授权等需要依赖后端或第三方服务自行管理它不包含内建安全特性。Next.js 是全栈框架可以直接在应用内构建后端 API 并管理安全。例如用 API 路由实现认证、保护敏感数据Next.js 的中间件Middleware还可以在页面渲染前检查认证状态。用于认证的 API 路由pages/api/secure-data.js// pages/api/secure-data.js export default function handler(req, res) { const { token } req.headers; if (token your-secret-token) { res.status(200).json({ message: You have access to secure data! }); } else { res.status(401).json({ error: Unauthorized access }); } }该 API 路由检查请求头中是否携带有效 token匹配则放行否则返回 401 错误。用中间件保护路由还可以用 Next.js 中间件检查用户认证来保护路由。典型逻辑是从请求如 cookies 或 headers中检查认证 token若 token 不存在把用户重定向到登录页若 token 存在请求正常继续。要把中间件应用到特定路由需将其放入项目根部的middleware.ts原文档写作middleware.js文件并按需配置匹配的路由。仓库实证refine 的 with-nextjs 示例的根布局 展示了一种服务端读取状态的写法——在 Server Component 中通过 Next.js 的cookies()读取themecookie 并透传给客户端上下文这正是 Next.js 全栈能力服务端可访问请求态的缩影而认证逻辑则被拆分在providers/auth-provider的 client/server 双文件中如 auth-provider.client.ts 所在目录与 Next.js 服务端/客户端组件分治 的模式一致。八、后端 API 开发React vs Next.jsReact 若要做后端 API离开 Express.js 或 Nest.js 这类 Node.js 后端框架就无从谈起而 Next.js 自带实现 API 路由所需的 Rust 语言架构使开发者可以在一个基于 React 的框架内开发后端 API。Next.js 的 API 路由在 Page Router 与 App Router 两种约定下均可用。Page RouterAPI 路由基于NextApiRequest与NextApiResponse这两个 API 构建并附带处理请求/响应的辅助方法App Router13 版本起可用 Next.js 的 Router Handlers 或 Server Components API 开发后端 API。九、配置差异React vs Next.js用 Create React App 创建的 React 应用需要手动处理配置这对 Babel 与 Webpack及其他工具的使用有较深的理解要求Next.js 则走最小配置哲学。9.1 React 的配置新建 React 项目最常见的方式是 Create React App它提供 Webpack、Babel 与开发服务器的搭建。但它把配置抽象掉了若不加eject弹出就不容易定制。定制 CRA 项目配置时需要eject该过程生成全部配置文件交出完全控制权但一旦 eject 就无法回退此后必须手动管理更新与配置。此外React 不强制特定文件夹结构——这带来灵活性的同时也要求团队自行确定并坚守一致的结构与架构以求稳定。React 也没有处理 CSS 的默认方式可用普通 CSS、CSS Modules或选择 styled-components 这类 CSS-in-JS 方案每种都需要较深入的配置与依赖。9.2 Next.js 的配置Next.js 的一大亮点是零配置zero-config无配置也能运行良好但需要定制行为时项目根部的next.config.js文件登场——默认的最小配置就预备在这个文件里。它可以定制 Next.js 的方方面面环境变量、Webpack 与 Babel 配置等。Next.js 还内建 TypeScript 支持只需往项目里加一个tsconfig.jsonNext.js 就会替你配置好 TypeScript。它开箱支持全局 CSS、CSS Modules 与 Sass也可以很容易地通过插件或自定义配置集成其他 CSS-in-JS 库。仓库实证with-nextjs 示例 恰好印证了最小配置哲学——其 next.config.mjs 仅两行有效配置唯一做的事是transpilePackages: [refinedev/antd]让 Next.js 转译 refine 的 antd 集成包而 tsconfig.json 中jsx: preserve、plugins: [{ name: next }]等条目则展示了 Next.js 约定好的 TypeScript 基线strict、moduleResolution: bundler、paths中* - ./src/*别名。示例的 package.json 声明next ^14.2.26、react ^19.1.0并依赖refinedev/nextjs-router ^7.0.5、refinedev/core ^5.0.12、refinedev/antd ^6.0.3即当前仓库中 Next.js 集成所对应的实际版本组合可作为升级/排查时的参考基线。十、适用场景何时用 Next.js何时用 React综合以上各层对比Next.js 把 React 的组件化架构与客户端渲染能力发挥到极致用服务端路由与服务端组件渲染实现全栈特性在服务器端与客户端两端静态/动态地生成页面。React 的极简与灵活在 Next.js 这类框架内部成为关键构件而 Next.js 的创新驱动模式则让高性能 React 应用得以横跨行业落地。何时使用 Next.jsNext.js 是电商网站、博客及其他基于页面的站点如社交媒体或垂直网络的理想选择。其强项在于混合渲染能力SSR、CSR、动态渲染与 SSG。在同一个应用中组合这些模式能有效保证快速页面加载——对于用户体验与即时可见性直接决定成败的电商与博客尤为重要。何时使用 ReactReact.js 的核心形态提供了高度可配置、灵活的基础特别适合构建小规模、简单而动态的单页应用SPA个人页面、落地页、作品集或任何需要频繁数据更新但对认证与路由需求很少的场景。这类应用受益于 React 的组件化架构可在无频繁页面刷新的前提下实现流畅交互。React 还适合像 Next.js 本身、refine或 Remix 那样从零构建完备的强健框架。只要有足够的资源、时间与要解决的问题你一定会愿意用极简主义从零起步围绕 React 建立自己的一套观点与约定。十一、快速起步分别启动两个项目11.1 启动一个 React 应用安装前提确保已安装 Node.js 与npm否则先从 Node.js 官方网站下载安装。用 Vite 初始化打开终端运行npm create vitelatest这会打开 Vite 的交互式 Shell提示输入项目名回车确认后选择框架为 React。进入应用目录cd react-app-name启动本地开发服务器npm install npm startReact 应用将运行在http://localhost:3000/注意Vite 项目通常使用npm run dev作为开发启动脚本具体以脚手架生成内容为准。11.2 初始化一个 Next.js 应用安装前提与 React 相同确保已安装 Node.js 与npm。确认3000端口没有被占用然后按以下步骤操作用npx在线 CLI 命令初始化 Next.js 项目npx create-next-app next-app-name进入应用目录cd next-app-name启动开发服务器npm run devNext.js 应用将运行在http://localhost:3000/。若之前 React 开发服务器仍占用3000端口可为它更换端口以避免冲突。仓库实证如果你希望直接在 Next.js 之上获得 refine 的 CRUD 能力认证、数据层、通知、路由等可用仓库示例提供的脚手架命令一键生成完整工程npm create refine-applatest -- --example with-nextjs生成的项目结构与 examples/with-nextjs 一致src/app下按资源组织页面src/providers下放置认证与数据 Provider根布局 中以Refine组件装配routerProvider、dataProvider、notificationProvider、authProvider与resources。十二、总结本文对比了 React 与 Next.js 的差异理解它们各自实现渲染模式的方式——尤其是 Next.js 如何依托 React 的客户端渲染能力并扩展出 SSR 及配套架构而这恰恰是许多 React SPA 所欠缺的。Next.js 作为更健壮的框架提供开箱即用的服务端路由、静态站点生成与数据获取功能支持全栈开发为大规模电商平台、拥有百万级静态页面的博客站点、基于页面的列表站点等场景提供可扩展方案而纯 React 则更适合落地页、作品集、个人页面这类以频繁用户操作与数据更新为主的简单 SPA。而在 refine 这类 headless 框架中二者的边界被进一步拉平无论你选择 Vite React Router 还是 Next.jsrefine 都提供对应的路由 Provider如 packages/nextjs-router与数据层抽象让同一套 CRUD 代码跑在不同的宿主框架之上——这本身也是React 打底、框架加约定这一父子关系在工程实践中的最佳注脚。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表