关于React18 RC你需要知道的
React是一个用于构建用户界面的 JavaScript 库,为什么再次强调呢?因为react18依然践行着他所坚持的理念,如何更好更快更优雅的进行用户界面的构建!
并发Rendering
如果要用一个词来总结整个React 18的发布,那一定是并发性。 并发性是一种幕后功能,它为这次更新中的许多特性提供了强大的支持,比如Suspense 和新的startTransition()和useDeferredValue()等api。
并发基本上意味着任务可以重叠。 与必须完全完成一个状态更新才能转移到下一个状态更新不同,并发性允许我们在多个状态之间来回切换。 需要注意的是,这并不意味着这些事情都在同一时间执行——相反,这是一项任务可以暂停,而其他更紧急的任务可以暂停。 然后,一旦更紧急的任务完成,我们可以跳回不那么紧急的任务,带来我们从更紧急的任务更新的信息。
React 18给我们提供的是处理和操作并发流的工具。 我们现在比以前更能控制呈现的优先级和顺序。
Suspense
React的代码的可读性很强。 对于开发人员来说,打开一个文件并从上到下阅读代码是相当容易的,这样可以快速理解组件中发生的事情。
但是当我们需要获取和处理数据时,我们经常需要异步请求后台和数据获取库,比如Apollo或React Query,它们提供了api和钩子,让他们可以跳过复杂的问题。
尽管有了这些解决方案,仍然有其他问题需要处理——主要是数据和加载状态内在联系的方式。 在此之前,我们必须指定某种类型的加载状态,然后根据该状态编写相应的JSX来有条件地呈现。 这意味着我们的UI元素总是绑定到特定数据块的加载状态。
const [loading, setLoading] = useState(true);
if myData != null {
setLoading(true);
}
<>
{ !loading &&
<MyComponent />
}
{ loading &&
<Loading />
}
<>
Suspense通过允许我们为尚未准备好显示的UI元素指定退路来解决这个问题。
<Suspense fallback={<Loading/>}>
<MyComponent myData={myData}/>
</Suspense>
它的灵感来自于设计原则——具体地说,是框架布局的概念,其中UI元素总是在适当的位置,并在内容准备好时填充。 这种方法能够帮助开发者编写更接近实际设计的代码,从而缩小原型和实际应用之间的差距。
我们并不仅仅局限于使用Suspense来处理数据,我们也可以将它用于流式服务器渲染。
服务器渲染呈现
服务器渲染是一种技术,你渲染你的React组件的HTML输出,然后在JS准备好之前把它发送给客户端,这样用户就不会盯着一个完全空白的页面。 在React 18之前,这是以全有或全无的方式发生的——当所有的组件都准备好了,页面就会更新,用户就可以开始与应用程序进行交互了。 这意味着,如果只有一个非常慢的组件,比如一个复杂的数据网格,那么一个组件就可能造成瓶颈。
Image from React 18 for App Developers slides.
现在,我们有了Suspense! 和之前谈到的一样,我们可以在那些标签中包装一个慢速组件,并告诉React延迟该组件的加载,而不是专注于先向下发送其他较小的组件。 您还可以,如前所述,设置一个回退来显示加载的动画。
Image from React 18 for App Developers slides.*
这允许用户在页面上的内容可用时,在一个组件一个组件的基础上,立即看到它,而不是等待一切就绪,然后立即获得全部内容。 您可以立即显示初始的HTML,然后将其余内容流化!
自动批量处理
在18以前,当一个事件处理程序中有多个状态更新时,就会发生批处理; 在这种情况下,React只会在函数结束时重新渲染一次——而不是每次状态改变的时候。 然而,这不会发生在事件处理程序之外——例如,如果在一个fetch或者axios调用中有多个状态更新,那么代码将为每个状态更新重新呈现。
fetch('http://example.com/data.json').then(() => {
setIsLoading(false);
setData(data);
setError(null);
});
//以前这个代码会导致3个不同的重新渲染,每次状态更新一次。
//现在,这三个更新将被打包成一个重新渲染。
现在,更新是自动批处理的,不管它们是用什么包装的。 不仅使得代码更加高效,而且也防止不必要的重新呈现。 然而,如果需要重新呈现发生,也可以选择退出特定的用例。
新的API
startTransition()
当我们使用startTransition API时,我们所做的就是将一些不那么紧急的动作标记为“过渡”,然后告诉React让其他更紧急的动作在呈现时间轴上优先执行。
从用户体验的角度来看,它会让事情变得更快速,对用户的反应更灵敏,同时也会减少我们作为开发者所投入的工作,从而将痛点最小化。 通过在startTransition中包装那些较慢、不那么紧急的更新,我们基本上可以告诉React,当它不忙于更重要的事情时,只去做那些更新是可以的。
这意味着转换可能会被更紧迫的更新所打断,React会暂停未完成的、现在已经过时的渲染工作,直接跳到新的内容。 这也意味着我们永远不会在呈现过时和不准确数据的组件上浪费时间。 或者,更糟糕的是,用户看到的信息不再正确。
onChange = (e) => {
const value = e.target.value;
startTransition(() => {
nonUrgentAction(value);
});
};
useTransition()
由于您的整个页面将不再被锁定等待这些漫长的进程,您的用户甚至可能没有意识到任何东西仍在加载!
出于这个原因,建议使用isPending,它也将作为useTransition钩子的一部分随React 18发布。 这个钩子返回startTransition函数,以及一个isPending值,当你的transition被渲染时,这个值将被设置为true。 通过这种方式,您可以快速检查isPending,以确定是否需要调整UI,以反映更新还没有完全准备好这一事实——例如,禁用一个按钮。
const [isPending, startTransition] = useTransition();
<Button className={isPending ? 'disabled' : 'active'} />
useDeferredValue()
新的useDeferredValue() API允许我们选择UI的特定部分,并有意推迟更新它们,这样它们就不会减慢页面的其他部分。 它有两个优点:(1)控制渲染顺序,(2)能够显示以前或以前的值,而不仅仅是加载动画或灰框。
正如上面所提到的,这是一个非常好的面向设计的更新。 没有什么比充满加载动画的页面更糟糕的了,很多时候,稍微旧一点的数据总比没有数据好。 这使得我们的组件永远不会感觉它们在加载,即使它们实际上是在后台。 对于用户来说,它只是更新! 多么可爱。
下面是如何使用它的一个例子:让我们假设我们正在从一个定期更新的数据源获取值,但是它有很多内容,通常需要一些时间来加载。 现在,使用useDeferredValue,我们可以允许在后台获取新数据,并通过让我们的组件使用value的旧内容(最长可达4000ms)来创建快速和平滑更新的假象。
const deferredValue = useDeferredValue(value, { timeoutMs: 4000 });
return (
<div>
<MyComponent value={deferredValue} />
</div>
);
跟ReactDOM.render说再见
在React 18中, 渲染语法以前用于将应用程序挂接到DOM上。 它被ReactDOM所取代。 createRoot,这是为了支持新特性必需要改变的。 你可以在不改变ReactDOM的情况下升级。 渲染和你的代码仍然可以工作,但你会在你的控制台得到一个错误,你将无法利用任何新东西在这个新发布。
// Before
import { render } from 'react-dom';
const container = document.getElementById('app');
render(<App tab="home" />, container);
// After
import { createRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App tab="home" />);
并发特性
如果你关注过过去的React更新,你可能已经听说过“并发模式”这个词。 这已经过时了——并发模式不再是React 18采用的策略。 相反,如果你听到“并发特性”。 正如React团队喜欢说的那样,“没有并发模式,只有并发特性!”
你可以添加在并发特性在你需要的个案基础上,而不必担心影响到应用程序的其余部分。 因为所有新的并发特性都是可选择的——例如,与任何自动设置的特性相比,必须通过将一个动作包装在setTransition中来声明它为一个转换——现有的代码不会受到这些更改的影响。 在默认情况下,React 18仍然会将所有的更新作为紧急更新处理,除非你利用任何并发特性告诉它不是这样。 这意味着你可以升级并有选择地开始将新特性添加到你的代码库中!
放弃对 Internet Explorer 的支持
在此版本中,React 将放弃对 Internet Explorer的支持,该支持将于 2022 年 6 月 15 日停止。我们现在进行此更改是因为 React 18 中引入的新功能是使用现代浏览器功能构建的,例如无法在 IE 中充分填充的微任务。
如果您需要支持 Internet Explorer,我们建议您继续使用 React 17。
那么现在是什么阻止了你升级呢? 升级到React 18 RC是快速和简单的,所以现在就开始利用所有的新特性在你的app中。 现在就开始吧,你可以在几周内准备好React 18的最终版本!
中充分填充的微任务。
如果您需要支持 Internet Explorer,我们建议您继续使用 React 17。
那么现在是什么阻止了你升级呢? 升级到React 18 RC是快速和简单的,所以现在就开始利用所有的新特性在你的app中。 现在就开始吧,你可以在几周内准备好React 18的最终版本!
react
官网博客:https://react.docschina.org/blog/2022/03/08/react-18-upgrade-guide.html