Next.js - React 的未来?为什么 React 并不完整?探索 Next.js 摘要

2025-06-04

Next.js——React 的未来?

为什么 React 并不完整

发现 Next.js

概括

React 和 Angular 可能是目前最热门的竞争框架。它们正被用于全球成千上万的商业和非商业项目。如果你曾经在 Google 上搜索过两者之间的区别,你会发现,尽管 React 是一个优秀的框架,但它并非完全具备开箱即用的体验。Angular 仍然有一些优势。但有了 Next.js,React可以克服其缺点,或许可以结束“React vs Angular”的旧有之争,最终以 React 的胜利告终。

为什么 React 并不完整

简而言之:它从未被设计成一个满足我们所有开发者需求的完整大型框架。它最初只是一个视图库——也就是 MVC 方法中的 V。它迅速革新了 Web,凭借 Flux 和 Redux 等新鲜概念获得了更大的人气。越来越多的开发者对它感到兴奋,并开始发布成百上千的中间件和实用程序,将这个主要以视图为中心的框架变得更加完整。现在,凭借其丰富的库生态系统,我们可以使用它来创建几乎任何我们能想到的应用程序。

问题在于,尽管社区提供了大量支持,但创建新的 React 项目却非常繁琐。即使使用Create React App,你仍然需要考虑并集成以下事项:

  • 国家管理,
  • 如果你恰好选择了 Redux,那么可以使用中间件来处理副作用,
  • 路由解决方案
  • 还有很多很多……

以最佳方式设置所有东西需要时间和经验。难怪有些开发者更喜欢 Angular。一旦安装,就可以开始开发了。Angular 附带了许多实用工具。值得注意的是:内置路由器、状态管理,以及约定优于配置的原则。它就是这么好用。

我们不能责怪 React 未能提供所有开箱即用的功能,因为这从来就不是它的初衷。幸运的是,Next.js 填补了这些空白,帮助我们快速上手!

发现 Next.js

那么 Next.js 是什么?它本质上是一个 React 框架。如果你认为 React 是一个框架(我就是这么认为的!),那么它就是一个框架的框架。它试图解决我之前提到的问题,并交付一个随时可用的平台。我们只需安装它,就能获得启动项目所需的一切(几乎)。无论是业余时间完成的热情项目,还是为大客户开发的商业项目,Next.js 都能满足我们的需求。让我们来看看它的功能。

简单设置

为了获得新的应用程序,我们所要做的就是在终端中输入以下内容:

yarn create next-app
Enter fullscreen mode Exit fullscreen mode

创建者会问我们两个问题:你的应用叫什么名字?你是否想使用模板?对于后者,我建议你使用默认选项。不过,如果你想尝试一下,也可以查看现有的模板。

一切完成后,我们得到以下结构

node_modules/
pages/
  api/
    hello.js
  index.js
public/
  favicon.ico
  vercel.svg
.gitignore
package.json
README.md
yarn.lock
Enter fullscreen mode Exit fullscreen mode

如果我们输入以下内容,我们的应用将以开发模式启动,并启用热重载!太酷了!输入以下内容即可实时查看你的页面http://localhost:3000

yarn dev
Enter fullscreen mode Exit fullscreen mode

提示:我建议将pages/文件夹移入,src/pages/以便我们可以将所有源文件保存到该src文件夹​​中。Next.js 也会使用src/pages

路由

如前所述,Next.js 内置了非常强大的路由功能。但它对新手来说可能有点不方便,因为它严重依赖于约定而非配置。所有放置在我们pages/或中的 JavaScript 文件src/pages都将映射到用户可以从浏览器访问的 URL。这些 URLpages/index.js可在页面根目录访问,pages/users.js也可以在mypage.com/users“等”处查看。对于更深层次的嵌套,您需要使用目录,这意味着它将pages/a/b/c.js变成mypage.com/a/b/c。就这么简单。

显然,如果 URL 不支持动态参数,我们就无法走得太远。幸运的是,Next.js 利用文件命名约定来帮助我们实现这一点。简单地说,要处理users/edit/{user-id}URL,只需创建文件即可。我们可以使用提供的钩子pages/users/edit/[userId].js访问该值userIduseRouter

import { useRouter } from 'next/router'

const Users  = () => {
  const router = useRouter()
  const userId = router.query.userId

  // rest of your logic
}

export default Users
Enter fullscreen mode Exit fullscreen mode

链接

作为路由的一个小福利,Next.js 内置了链接解决方案。next/link该组件包含在包中,可以帮助我们以更优化的方式链接到页面。

<Link href="/users/[userId]" as="/users/1">
  <a>See the first user</a>
</Link>
Enter fullscreen mode Exit fullscreen mode

Link除了传统的 之外,我们还可以使用提供a的 ,从而利用默认启用的预加载功能,从而加快页面加载速度。此外,即使在服务器端渲染模式下,Link也允许我们在客户端实际渲染页面,使其成为一种智能的 SSR/SPA 混合体。

有许多选项Link,因此我们可以非常轻松地更改其行为以使用history.replace而不是调用history.push或仅执行浅层渲染(更新 URL 而不更新页面内容)。

API 支持

接下来我们将深入探讨更高级的功能。Next.js 不仅仅是一个纯粹的前端框架。有了它,我们还可以非常轻松地开发后端端点。

按照路由约定,pages/api目录内的每个文件都会变成一个我们可以从浏览器调用的端点。默认文件向api/hello.js我们展示了创建返回 JSON 数据的有效端点是多么简单:

export default (req, res) => {
  res.statusCode = 200
  res.json({ name: 'John Doe' })
}
Enter fullscreen mode Exit fullscreen mode

从现在开始,没有什么可以阻止我们执行后端逻辑,例如查询数据库。我们只需要安装我们最喜欢的 ORM,就可以开始了。

服务器端渲染

这是让我惊叹的功能之一。Next.js 对 SSR 的支持非常出色!我之前参与过一个项目,客户决定启用 SSR。但我们把所有东西都开发成了客户端渲染页面。幸运的是,Next.js 帮助我们快速完成了切换。

作为示例,让我们考虑这个非常简单、完全客户端呈现的页面:

// pages/todo/[id].js
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router'

const Todo = () => {
  const [data, setData] = useState(null);
  const router = useRouter()
  const id = router.query.id

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/todos/' + id)
      .then(response => response.json())
      .then(json => setData(json))
  }, [id])

  return <div>Todo - {data ? data.title : 'loading...'}</div>
}

export default Todo
Enter fullscreen mode Exit fullscreen mode

为了将其转换为完全服务器端渲染的页面,我们只需要导出名为的附加异步函数getStaticProps并将我们的数据获取逻辑移动到那里。

// pages/todo/[id].js
import React from 'react';

const Todo = ({ data }) => {
  return <div>Todo - {data.title}</div>
}


export const getStaticProps = async (ctx) => {
  const id = ctx.params.id;
  const data = await fetch('https://jsonplaceholder.typicode.com/todos/' + id)
    .then(response => response.json());

  return {
    props: {
      data
    }
  }
}

export default Todo;
Enter fullscreen mode Exit fullscreen mode

我们刚刚把 CSR 页面改造成了一个完整的 SSR 页面。简直太简单了!

静态页面生成器

有时我们只需要生成一个简单的静态页面,而无需使用 Node.js 服务器。Next.js 以与 SSR 非常类似的方式,允许我们快速创建静态生成的页面。让我们考虑一下 SSR 示例——我们只需要导出一个额外的方法,getStaticPaths该方法会告诉 Next.js 有哪些可用的 ID。

显然,如果我们基于数据库或某些 CMS 生成网站,则需要在此处检索所有有效 ID。最后,只需返回包含所有 ID 的对象即可。静态生成页面的完整代码如下:

// pages/todo/[id].js
import React from 'react';


const Todo = ({ data }) => {
  return <div>Todo - {data.title}</div>
}


export const getStaticProps = async (ctx) => {
  const id = ctx.params.id;

  const data = await fetch('https://jsonplaceholder.typicode.com/todos/' + id)
    .then(response => response.json());

  return {
    props: {
      data
    }
  }
}


export const getStaticPaths = async () => {
  return {
    paths: [
      { params: { id: '1' } },
      { params: { id: '2' } },
      { params: { id: '3' } }
    ],
    fallback: false
  };
}

export default Todo;
Enter fullscreen mode Exit fullscreen mode

用这种方式准备好所有页面后,我们只需调用next buildnext export命令即可。瞧,我们的静态页面生成了!更让我印象深刻的是,几乎所有的路由功能(比如预取)在静态页面中都能正常工作。

TypeScript 支持

如果您和我一样,喜欢在项目中使用类型,那么 Next.js 是完美的选择。虽然它不会生成 TypeScript 项目,但可以轻松转换为 TypeScript 项目。我们只需tsconfig.json在根目录中创建一个空文件并运行我们的应用程序即可。Next.js 会将其初始配置填充到配置中,然后就可以使用我们的 TypeScript 代码了。就这么简单!

唉,还是有一些小问题需要注意。首先,最好不要更改 中的现有属性tsconfig.json。例如,在一个项目中,我尝试禁用 标志skipLibCheck,但这导致编译器在 Next.js 的一个依赖项中抛出错误。因此,我强烈建议不要更改现有配置。不过,添加新属性还是挺酷的!

其次,文档主要针对老旧的 JS 编写。这意味着有时查找函数参数的类型可能会有问题。例如,让我们再次看一下 API 支持中的示例:

export default (req, res) => {
  res.statusCode = 200
  res.json({ name: 'John Doe' })
}
Enter fullscreen mode Exit fullscreen mode

我们需要仔细研究文档,弄清楚使用时,该req对象实际上是类型。虽然这没什么大不了的,但查找类型确实有点烦人。NextApiRequestresNextApiResponse

缺点

Next.js,如同生活中的一切,并非完美无缺,也存在自身的缺陷。你是否注意到,我竟然没有提到任何关于状态管理的内容?这是因为 Next.js 虽然功能丰富,却没有提供内置的状态管理器。它如此出色,如此随时可用,却没有状态管理,这着实令人失望。

但我觉得这很有道理。最近,React 应用的状态管理成了一个颇具争议的话题。很多人说 Redux 很棒(包括我自己,但我也承认它有缺陷)。另一方面,也有人说 MobX 才是最佳选择。最后,还有一些开发者会争辩说,Context API 就足够了,或者unstated-next可以使用一些更奇特的方案(我不推荐)。鉴于这些争议,Next 的开发者们没有只选择一个解决方案也就不足为奇了。此外,说实话,对于这样一个功能如此强大的工具,找到最佳解决方案可能并不容易。

但是如果我们的应用程序中确实需要状态管理器,网络上有很多教程展示如何快速添加 Redux 或 MobX。

Next.js 的另一个(虽然不大)缺点是缺乏对任何 CSS-in-JS 技术的开箱即用支持。我们可以从一开始就使用 CSS 和 SCSS。但是,当涉及到更现代的样式方法时,我们需要添加一些代码。不过,代码量并不大,官方文档(此处)中提供了示例链接。

概括

由此可见,Next.js 是一款出色且功能丰富的 React 框架。它提供了一个配置良好、开箱即用的环境,可用于创建几乎任何 Web 应用。基本上,Next 非常适合单页应用、服务器端渲染页面、静态生成页面以及介于两者之间的任何应用。借助 API 支持,我们可以使用它创建包含后端逻辑的完整页面。唯一一个很大的缺点是它没有内置状态管理器。除此之外,它具备我们快速创建新 Web 应用所需的一切。

总而言之,我相信它拥有目前最完整的 React 体验。Next.js 提供了纯 React 所缺乏的所有功能,使其成为在“React vs Angular”之争中与 Angular 正面交锋的强大工具。如果 React 想要赢得这场争论,它需要一个坚实的框架。在我看来,Next.js 正是如此,它是一个适用于现代 Web 应用开发的绝佳环境。

文章来源:https://dev.to/dotintegral/next-js-the-future-of-react-21nb
PREV
.Net Core 中你不可或缺的 10 个命令
NEXT
使用 CSS 变量和 React Context 的主题