对于现代网络开发者来说,并不缺乏JavaScript库和框架。最普遍的库之一是React,它是Facebook(现在的Meta)创建的,以帮助建立功能丰富的应用程序。React应用程序传统上在网络浏览器中运行,但Next.js框架通过JavaScript运行环境Node.js将React功能扩展到服务器端。
在这篇文章中,我们将了解Next.js和React,以便你能决定它们是否适合你的下一个项目。
Next.js和React:升级版本的JavaScript
2022年的SlashData调查发现,全世界有超过1700万的JavaScript程序员,在包括Python和Java等流行语言在内的队伍中处于领先地位。JavaScript可以在客户端和服务器端使用,这种通用性意味着开发者可以使用一种编程语言建立完整的应用程序。
Slash/Data对2022年程序员使用的语言的调查。(来源:Statista)
React等JavaScript库和Next.js等框架的引入进一步加强了这种发展。这些库和框架提供的功能简化了前端和后端的整合。此外,开发人员可以使用npm(Node.js包管理器)等包管理器来安装JavaScript库和工具,扩展JavaScript功能。这些资源提供了复杂的功能,减少了你必须自己编写的代码量。
JavaScript的可扩展性意味着对其最常用的工具的全面了解是你作为一个网络开发者成功的关键。
什么是Next.js?
Next.js最初由Vercel在2016年发布,是一个开源的React框架,提供了创建高性能网络应用的构建块。此后,主要公司都采用了它,包括Twitch、TikTok和Uber,等等。
Next.js为构建快速、SEO友好的应用程序提供了最好的开发者体验之一。以下是Next.js的一些特点,使其成为一个出色的生产框架:
- 混合渲染能力
- 自动代码拆分
- 图像优化
- 内置对CSS预处理器和CSS-in-JS库的支持
- 内置路由
这些功能帮助Next.js开发人员节省了大量配置和工具的时间。你可以直接跳到构建你的应用程序,它可能支持以下项目:
- 电子商务商店
- 博客
- 仪表板
- 单页应用程序
- 交互式用户界面
- 静态网站
什么是React?
React是一个用于构建动态用户界面的JavaScript库。除了创建网页界面外,你还可以使用React Native构建移动应用程序。
使用React的一些好处包括:
- 提高性能:React使用一个虚拟DOM,而不是更新DOM中的每个组件,只更新已更改的组件。
- 重度基于组件:一旦你创建了一个组件,你可以重复使用它。
- 易于调试:React应用程序使用单向的数据流–只从父组件到子组件。
Next.js vs React
尽管开发者经常将Next.js和React用于相同的目的,但两者之间有一些根本的区别。
易于使用
开始使用Next.js和React很容易。两者都需要在终端使用 npx
运行单个命令,这是Node.js的npm的一部分。
对于Next.js,最简单的命令是:
npx create-next-app
在没有额外参数的情况下,create-next-app
的安装将以交互模式进行。你将被要求提供一个项目名称(将用于项目目录),以及你是否要包括对TypeScript和代码linter ESLint的支持。
它看起来会像这样:
在interactive模式下创建Next.js应用程序。
在初始化React实例时,最简单的命令包括项目的目录名称:
npx create-react-app new-app
这将生成一个包含所有必要的初始配置和依赖性的文件夹:
在终端命令行上创建一个React项目。
虽然两者都能让你轻松上手,但请记住,Next.js是建立在React之上的。因此,如果不先学习React并了解它的工作原理,你就无法学习Next.js。幸运的是,React拥有一个温和的学习曲线,很适合初学者。
同样重要的是要注意,React是相对非结构化的。你必须安装和设置React路由器,并决定如何处理数据获取、图像优化和代码拆分。这种设置需要你安装和配置额外的库和工具。
相比之下,Next.js 预先安装和配置了这些工具。有了Next.js,任何添加到 pages
文件夹中的文件都会自动作为路由。由于这种内置支持,Next.js更容易进行日常工作,使你能够立即开始编码你的应用程序的逻辑。
Next.js和React的特点
因为Next.js是基于React的,两者共享一些功能。然而,Next.js更进一步,包括额外的功能,如路由、代码拆分、预渲染和开箱即用的API支持。这些是你在使用React时需要自己配置的功能。
数据获取
React在客户端渲染数据。服务器向浏览器发送静态文件,然后浏览器从API中获取数据以填充应用程序。这个过程降低了应用程序的性能,并提供了糟糕的用户体验,因为应用程序加载缓慢。Next.js通过预渲染解决了这个问题。
通过预渲染,服务器在向浏览器发送应用程序之前会进行必要的API调用并获取数据。因此,浏览器收到的是可随时渲染的网页。
预渲染可以指静态网站生成(SSG)或服务器端渲染(SSR)。在SSG中,HTML页面是在构建时生成的,并在多个请求中重复使用。Next.js可以生成带或不带数据的HTML页面。
下面是一个例子,说明Next.js如何生成没有数据的页面:
function App() { return <div>Welcome</div> } export default App
对于消耗外部数据的静态页面,使用 getStaticProps()
函数。一旦你从一个页面导出 getStaticProps()
,Next.js将使用它返回的props对页面进行预渲染。这个函数总是在服务器上运行,所以当页面使用的数据在构建时是可用的,就使用 getStaticProps()
。例如,你可以用它来从CMS中获取博客文章。
const Posts= ({ posts }) => { return ( <div className={styles.container}> {posts.map((post, index) => ( // render each post ))} </div> ); }; export const getStaticProps = async () => { const posts = getAllPosts(); return { props: { posts }, }; };
在页面路径依赖于外部数据的情况下,使用 getStaticPaths()
函数。因此,要根据帖子的ID创建一个路径,从页面导出 getStaticPaths()
。
例如,你可以从pages/posts/[id].js导出 getStaticPaths()
,如下所示:
export getStaticPaths = async() => { // Get all the posts const posts = await getAllPosts() // Get the paths you want to pre-render based on posts const paths = posts.map((post) => ({ params: { id: post.id }, })) return { paths, fallback: false } }
getStaticPaths()
经常与 getStaticProps()
配对使用。在这个例子中,你会用 getStaticProps()
来获取路径中的ID的详细信息。
export const getStaticProps = async ({ params }) => { const post = await getSinglePost(params.id); return { props: { post } }; };
在SSR中,数据在请求的时间被获取并被发送到浏览器。要使用SSR,从你要渲染的页面中导出 getServerSide()
道具函数。服务器在每次请求时都会调用这个函数,这使得SSR对于消耗动态数据的页面非常有用。
例如,你可以用它来从一个新闻API中获取数据。
const News = ({ data }) => { return ( // render data ); }; export async function getServerSideProps() { const res = await fetch(`https://app-url/data`) const data = await res.json() return { props: { data } } }
这些数据在每次请求时被获取,并通过props传递给新闻组件。
代码拆分
代码拆分是将代码分成几块,让浏览器可以按需加载。它减少了初始加载时发送到浏览器的代码量,因为服务器只发送用户需要的内容。Webpack、Rollup和Browserify等捆绑程序支持React中的代码分割。
Next.js支持开箱即用的代码拆分。
使用Next.js,每个页面都是代码拆分的,向应用程序添加页面不会增加捆绑程序的大小。Next.js还支持动态导入,允许你导入JavaScript模块,并在运行时动态加载它们。动态导入有助于提高页面速度,因为捆绑是懒得加载的。
例如,在下面的Home组件中,服务器不会在初始捆绑中包括英雄组件。
const DynamicHero = dynamic(() => import('../components/Hero'), { suspense: true, }) export default function Home() { return ( <Suspense fallback={`Loading...`}> <DynamicHero /> </Suspense> ) }
相反,悬念的回退元素将在英雄组件加载之前被渲染。
Next.js对React的API支持
Next.js的API路由功能使您能够在同一代码库中编写后端和前端代码。任何保存在/pages/api/文件夹中的页面都会被映射到/api/*路由中,Next.js会将其视为API端点。
例如,你可以创建一个 pages/api/user.js 路由,像这样返回当前用户的名字:
export default function user(req, res) { res.status(200).json({ username: 'Jane' }); }
如果你访问 https://app-url/api/user 链接地址,你会看到用户名对象。
{ username: 'Jane' }
当你想掩盖你正在访问的服务的URL或想保持环境变量的秘密而不需要编写整个后端应用程序时,API路由很有帮助。
性能方面
Next.js在以简化的程序创建性能更好的应用程序方面无疑是卓越的。SSR和SSG Next.js应用程序比客户端渲染(CSR)React应用程序性能更好。通过在服务器上获取数据并发送浏览器需要渲染的所有内容,Next.js消除了对API的数据获取请求的需要。这意味着更快的加载时间。
此外,由于Next.js支持客户端路由。浏览器不需要在用户每次导航到另一个路由时从服务器获取数据。此外,Next.js的图像组件能够自动优化图像。图片只在进入视口时才加载。在可能的情况下,Next.js还以WebP等现代格式提供图像。
Next.js还提供字体优化、智能路由预取和捆绑优化。这些优化在React中并不自动可用。
支持
由于React比Next.js存在的时间长,它有一个更广泛的社区。然而,许多React开发人员正在采用Next.js,所以该社区正在稳步增长。开发人员更容易找到他们遇到的问题的现有解决方案,而不是从头开始构建解决方案。
Next.js还具有优秀的文档,有全面的例子,易于理解。尽管它很受欢迎,但React的文档却没有那么容易浏览。
小结
选择Next.js还是React要看应用程序的要求。
Next.js通过提供改善性能的结构和工具,增强了React的能力。这些工具,如路由、代码分割和图像优化,都内置于Next.js中,这意味着开发人员不必手动配置任何东西。由于这些功能,Next.js很容易使用,开发者可以立即开始对业务逻辑进行编码。
由于有不同的渲染选项,Next.js适用于服务器端渲染的应用程序或结合静态生成和Node.js服务器端渲染的应用程序。另外,由于Next.js提供的优化功能,它非常适合于需要快速的网站,如电子商务商店。
React是一个JavaScript库,可以帮助你创建和扩展强大的前端应用程序。它的语法也很简单,特别是对于有JavaScript背景的开发者来说。此外,你可以控制你在应用程序中使用的工具,以及你如何配置它们。
评论留言