这是全网唯一一本正儿八经介绍 React 19 的付费专栏。
到目前为止,大家总体上来说,对 React 19 的认可度并不高,粗浅的认为他只是做了一些简单的改动,包括官方文档,也只是简单罗列出了它新增了一些 hook,一些特性,却并没有进一步说明这些 hook 背后所代表的具体含义.
以至于,在这个时间节点,期待 React 19 的人也并不是很多。
但是,我要告诉大家的是,我们都严重低估了 React 19。
经过我长达一整年的使用体验,我的感受是:
我们的开发方式,正在迎来一次重大升级。 因为新的 hook 真的太好用了。
所以我准备写一系列合集,为大家完整、详细的介绍 React 19 的新的最佳实践。在后续的文章中,我会详细分析新的开发方式的思考。
和过去的 React 版本相比,React 19 主要从如下两个方面带来了显著的提升。
最近几年,许多其他前端框架纷纷拥抱基于 Signal 的细粒度更新,在特定场景有接近原生开发的性能体验,把前端框架的性能问题推上了风口浪尖。而 React 基于 Fiber 的 Diff 更新则自然而然的成为了最大的缺陷与短板。大量冗余 re-render 造成的性能损耗,是 React 不得不面对的挑战。
注:细粒度更新并非所有场景都具有明显的优势,也不要完全相信框架而忽视掌握性能优化技能的重要性
虽然 React 提供了 memo/useMemo/useCallback
来帮助开发者优化项目性能。但是他们的学习成本并不低,想要在项目中得心应手的使用他们更是不易。这就造成了许多团队在没有完全消化他们的情况下,对他们的使用存在滥用的情况。
在这样的背景之下,React 19 推出了 React Compiler,在开发者不调整任何代码的情况下,自动优化项目性能。
React Compiler 能够帮助我们在不使用 memo/useMemo/useCallback
的情况下,方便得处理好项目 re-render 的问题。你的项目最终只会在需要更新的地方 re-render。
并且最重要的是,React Compiler 编译之后,你的代码并不会改变现有渲染机制,而是在已有机制下完成对项目的优化。React Compiler 的愿景非常庞大,他需要在兼顾大量老项目的情况下,做到对项目的性能优化。因此与提出一个新的解决方案相比,他的开发难度要高出很多。破坏性更新显得更加容易,但是对于开发者和大量老项目而言,这是一种严重的伤害。React Compiler 则选择了最难搞的一种更新方式。
与依赖追踪的细粒度更新不同,React Compiler 通过记忆的方式,让组件更新只发生在需要更新的组件,从而减少大量 re-render 的组件,我会在后续的章节中详细介绍他的使用原理。
但是请注意,React Compiler 并非全能,如果你写的代码过于灵活,无法被提前预判执行行为,那么 React Compiler 将会跳过这一部分的优化。因此好的方式是在项目中引入严格模式,在严格模式的指导下完成的开发,基本都在 React Compiler 的辐射范围之内
与性能带来的提升相比,真正令我非常期待的是,React 19 将会迎来一次开发体验的重大提升。毕竟没有 React Compiler,我自己也能优化好我的项目性能。
开发体验的提升主要体现在,React 19 之后,我们可能不再那么需要 useEffect
了。
useEffect 是一个功能强大的 hook,但他又是最难驾驭的一个 hook,理解不够的开发者可能会由于滥用它而导致项目失控。包括被讨论最多的闭包问题,也往往跟它有关。其中最考验开发者水平的,是对于 useEffect 依赖项的正确处理。
React19 的大部分更新,几乎都是围绕如何在开发中尽量不用或者少用 useEffect 来展开。在之前的项目开发中,useEffect
是我们处理异步问题必须使用的重要 hook 之一,他几乎存在于每一个页面组件之中。
React 19 则引入了新的 hook,让我们处理异步开发时,不再需要 useEffect
,从而极大的改变我们的开发方式。我会在后续的章节中,结合大量实践案例,一一介绍这些 API 的详细使用方法,确保每个读者都能彻底掌握他。
除此之外,React19 想要彻底改变我们在项目开发中的 UI 交互方式。对于 React19 而言,Suspense
的重要性将会变得越来越高, 瀑布流式的开发方式将会被认可。
Suspense
虽然早在 React18 中都能够被正常使用,但是由于异步请求方案的不成熟,它们并没有被普及开,包括 React 官方文档也并没有进一步说明如何触发 Suspense
的回调机制。因此它们只是小范围的被一些顶尖的前端开发所使用。
1<Suspense fallback={<div>loading...</div>}>2<List api={__api} />3</Suspense>
React19 之后,它们将会得到普及。这将会进一步深化组件解释一切的开发思想。
React 19 之前,React 高手与普通开发者之间,开发的项目无论是从性能上、还是从代码优雅上差距都非常大。因此不同的人对于 React 的感受完全不一样。
而 React 19 则借由推出一些新的 hook,暗中传递一种框架思维「最佳实践」,这将会极大的拉进普通开发者与顶尖高手之间的差距。对于大多数 React 开发者而言,这会是一个极大的提升。
这一意图在 React 新的官方文档与 Next.js 中体现得非常明显
这一最佳实践主要围绕如何改进异步编程的开发体验而展开。在后续的章节中大家可以自行感受。我也会在后续的实践案例中弱化对 useEffect
的使用。
例如,当我想要实现如下效果时。
在项目开发中,新页面渲染时请求一个接口的场景非常常见。新的架构思维的开发代码如下所示。
该案例没有引入任何三方库
首先我们需要定义一个 API 用于请求数据。
10import { createRandomMessage } from '@/utils';2030var requestOptions: RequestInit = {40method: 'GET',50redirect: 'follow'60};7080const url = 'https://randomuser.me/api/?results=2&inc=name,gender,email,nat,picture&noinfo'9010export const getApi = async () => {11await fetch(url, requestOptions)12return { value: createRandomMessage()}13}14
需要注意的是,本案例中的 api 都使用的是模拟接口,许多数据无任何业务描述,仅用于呈现 UI 的显示和变化。因此写法会与实际开发过程中稍有差异。
然后创建一个函数组件,并执行该 api
10import { Suspense } from 'react'20import Message from './message'30import Skeleton from 'components/ui/skeleton'40import { getApi } from '../api'5060export default function App() {70const promise = getApi()8090return (10<Suspense fallback={<Skeleton type='header' />}>11<Message response={promise} />12</Suspense>13)14}15
最后在子组件中,获取 api 执行之后得到的数据
10import { use } from 'react'20import { getApi } from '../api'3040const Message = (props: { response: ReturnType<typeof getApi> }) => {50const content = use(props.response)6070return (80<div className='leading-6 transition border rounded-md p-4 text-gray-600 border-gray-200 my-4'>90{content.value}10</div>11)12}13export default Message14
演示效果如下
10import { Suspense } from 'react'20import Message from './message'30import Skeleton from 'components/ui/skeleton'40import { getApi } from '../api'5060export default function App() {70const promise = getApi()8090return (10<Suspense fallback={<Skeleton type='header' />}>11<Message response={promise} />12</Suspense>13)14}15
大家可以自行感受一下新的开发方式与以前基于 useEffect
请求数据有什么不同之处。
我在下方案例演示中,还提供了更完整更具代表性的案例。大家可以先瞄一眼体会一下
10import { Suspense, useState, useTransition } from 'react'20import Skeleton from 'components/ui/skeleton'30import Message from './message'40import { getApi } from '../api'5060export default function App() {70const [response, setApi] = useState(getApi)80const [isPending, startTransition] = useTransition()9010function __click() {11startTransition(() => {12setApi(getApi())13})14}1516return (17<div className='space-y-4'>18<div className='flex justify-end'>19<button className='button' onClick={__click} disabled={isPending}>点击更新</button>20</div>2122<Suspense fallback={<Skeleton />}>23<Message response={response} isPending={isPending} />24</Suspense>25</div>26)27}28
注意:一套成熟架构思维,不是使用一个简单的方案解决某一个问题,而是要基于这套思维去解决项目中的绝大多数场景。因此我们一定要结合大量的场景去理解一套项目架构思维。
很显然,在处理异步逻辑时,React 19 的方式与过去大有不同。除此之外,我还发现,并发模式将会更加容易被运用到普通开发中,从而极大提高交互体验。
React 19 绝对是值得所有 React 开发者立即学习掌握并运用于项目实践中的技术方案。在未来几年内他可能会被大量开发中逐步接受,而我们则可以直接借助这本专栏的学习,成为先行者。
本专栏名为:「React19 全解」。在这里我基于沉浸式的学习体验,内置了大量可操作可交互的真实案例。摒弃了使用截图演示案例的方式。除此之外,为了让大家能够获得更好的学习效果,每一个案例都精心设计了 UI。在细节上精心打磨,争取让大家能够所学即所得。快速掌握 React19.
希望大家能够在这里获得全网最好的学习体验!Let's go.