React 18,它来啦!

5,145 阅读9分钟

译自原文:18.0.0 (March 29, 2022)

版本:18.0.0,发布时间:2022.3.29,Tag:Lastest

以下是所有新特性、 api、弃用和破坏性变更的列表。

阅读React 18 发布和React 18升级指南获取更多信息。

新特性

React

  • useId是一个新hook,用于在客户端和服务端生成唯一ID,为了避免注水时的不匹配。主要在组件库和需要唯一id的api集成时使用。这解决React 17以下版本出现的一个issue,但更重要的是在React 18中解决新的流式服务渲染器如何传递无序HTML的问题。

  • startTransitionuseTransition可以让你更新一些不紧急的state。其它state的更新默认视为紧急。React会允许紧急的state更新(例如,输入框内容更新)来打断不紧急的state更新(例如,渲染搜索结果)。

  • useDeferredValue可以让你推迟不紧急部分的渲染树的重新渲染。这有点像防抖,但是和它相比有一些其它的优势。它没有固定的时间延迟,所以React会在第一次渲染更新到屏幕后马上尝试延迟渲染。这个延迟渲染是可中断的并且不会阻塞用户输入。

  • useSyncExternalStore是一个用于解决CSS-in-JS库在渲染中注入样式的性能问题的新hook。如果你不是已经在搭建一个CSS-in-JS库,你永远不需要使用它。这个钩子紧接着在DOM异变后,layout effects读取新的layout之前运行。这解决React 17以下版本出现的一个issue,但更重要的是在React 18中,React会在并发渲染中向浏览器屈服,让它有一个重新计算布局的机会。

React DOM Client

这些新的API现在从react-dom/client包中导出:

  • createRoot:创建用于renderunmout的根节点。用它代替ReactDOM.render。没有它,React 18的新特性就不能工作。
  • hydrateRoot:一个给服务端渲染程序注水的新方法。用它替代ReactDOM.hydrate和React DOM服务端api一起使用。没有它,React 18的新特性就不能工作。

createRoothydrateRoot都接受一个新的选项参数名为onRecoverableError,用于当你想在React渲染过程从错误中恢复时或者注水时是查看日志时使用。默认情况下,React会使用reprotError,或者在低版本浏览器中使用console.error

React DOM Server

这些新的API现在从react-dom/server包中导出,并且在服务端完全支持流式Suspense:

  • renderToPipeableStream:用于Node环境中的流。
  • renderToReadableStream:用于现代边缘端运行环境,如Deno和CloudFlare workers。

现有的renderToString方法可以继续工作,但不推荐使用。

废弃

  • react-domReactDOM.render被废弃。使用它会发出一个警告并且会将你的app降级以React 17的模式运行。
  • react-domReactDOM.hydrate被废弃。使用它会发出一个警告并且会将你的app降级以React 17的模式运行
  • react-dom: ReactDOM.unmountComponentAtNode 被废弃。
  • react-dom: ReactDOM.renderSubtreeIntoContainer 被废弃。
  • react-dom/server: ReactDOMServer.renderToNodeStream 被废弃。

破坏性变更

React

  • 自动化批处理:这个版本引入了性能改进,改变了React批处理更新的方式,可以自动进行更多的批处理。详情查看Automatic batching for fewer renders in React 18 。在极少数情况中,你需要选择退出和打包state更新时,使用flushSync

  • 更严格的严格模式:在未来, React将提供一个特性,让组件在卸载之间保持状态。未来准备实现它, React 18在严格模式中引入了一个新的development-only检查。 每当组件第一次挂载时,React会自动卸载和重新挂载每个组件,在第二次挂载时恢复之前的状态。如果这破坏了你的应用程序,考虑取消严格模式,直到你可以修复组件,以适应使用现有状态执行重新安装。

  • 一致的useEffect时机:如果更新触发分散在用户的输入事件,如点击或keydown事件,React现在会同步刷新effect函数。在以前,行为并不总是可预测或一致的。

  • 更严格的注水错误:由于缺少或额外的文本内容而导致的注水操作不匹配现在被视为错误而不是警告。React将不再尝试通过在客户机上插入或删除一个节点来“修补”单个节点,以匹配服务器标记,而会告诉客户端渲染到树中最近的<Suspense>边界。这确保了注水树的一致性,并避免了注水不匹配可能导致的潜在隐私和安全漏洞。

  • 挂起(Suspense)树总是一致的:如果组件在完全添加到树之前挂起,React将不会在不完全状态下将其添加到树中,也不会触发其effects。相反,React会完全抛弃新树,等待异步操作完成,然后重新尝试渲染。React将并发地尝试渲染重试工作,而不会阻塞浏览器。

  • 带挂起功能的Layout Effects:当一棵树重新挂起并恢复到回退状态时,React现在会清理layout effects,然后在边界内的内容再次显示时重新创建它们。这修复了组件库在使用挂起时无法正确测量布局的问题。

  • 新的JS环境要求:React现在依赖于现代浏览器的特性,包括PromiseSymbolObject.assign。 如果您需要支持较老的浏览器和设备,如Internet Explorer,它们没有提供现代浏览器的原生特性或有不兼容的实现,请考虑在打包的应用程序中包含一个全局polyfill。

显著变更

React

  • 组件现在可以渲染undefined:如果你从组件返回undefined, React就不再抛出。这使得允许的组件返回值与组件树中间允许的值一致。 我们建议使用一个linter来防止像在JSX之前忘记return语句这样的错误。

  • 在测试中,act警告现在是可选择的:如果你在运行端对端测试,act警告是不必要的。我们引入了一种选择加入机制,因此您可以仅在单元测试中启用它们,因为它们是有用和有益的。

  • 在卸载组件上没有关于setState的警告:以前,当你在卸载的组件上调用setState时,React会发出一个内存泄漏的警告。个警告是为订阅添加的,但人们主要是在设置状态正常的情况下才 会遇到它,而尝试解决这个警告会使代码变得更糟。我们已经移除了这个警告。

  • 控制台日志没有被抑制屏蔽:当你使用严格模式时, React将每个组件渲染两次,以帮助您发现意外的副作用。在React 17中,我们屏蔽了其中一个渲染的控制台日志,以使日志更容易阅读。为了回应社区对于这一令人困惑的反馈,我们取消了屏蔽。相反,如果你安装了React DevTools,第二个日志的渲染将以灰色显示,并且会有一个选项(默认关闭)来完全屏蔽它们。

  • 改进的内存使用情况:React现在在卸载时清理更多的内部字段,使应用程序代码中可能存在的未修复内存泄漏的影响不那么严重。

React DOM Server

  • renderToString: 在服务器挂起时不再出错。相反,它将为最近的<Suspense>边界发出回退HTML,然后在客户机上重试渲染相同的内容。仍然建议你改用像renderToPipeableStreamrenderToReadableStream这样的流API。

  • renderToStaticMarkup:在服务器挂起时不再出错。相反,它将为最近的<Suspense>边界发出回退HTML,然后在客户端重试渲染。

所有变更

React

  • 添加useTransitionuseDeferredValue将紧急更新在转换时分离开来。

  • 添加useId用于生成唯一的id。

  • 添加useSyncExternalStore来帮助外部存储库与React集成。

  • 添加startTransition作为不需要等待反馈版的useTransition

  • 当内容重新出现时,使挂起重新安装layout effects。

  • 使<StrictMode>重新运行effects来检查可恢复状态。

  • 假设Symbols总是可用的。

  • 移除 object-assign polyfill.

  • 移除不支持的 unstable_changedBits API.

  • 允许组件渲染undefined。

  • 在离散事件(如同步单击)触发时同步Flush useEffect

  • 挂起中的fallback={undefined}现在效果和null一样,没有被忽略。

  • 将所有lazy()视为解析相同的等效组件。

  • 不在第一次渲染时patch控制台。

  • 提高内存使用。

  • 改进字符串强制转换抛出时的消息(Temporal.*, Symbol等)。

  • MessageChannel可用时,使用setImmediate

  • 修复上下文无法在挂起树内部传播的问题。

  • 修复useReducer`在移除 eager bailout mechanism时观察到错误属性的问题。

  • 修复在Safari中添加iframes时setState被忽略的问题。

  • 修复在树中渲染ZonedDateTime时的崩溃问题。

  • 修复测试中文档被设置为null时的崩溃问题。

  • 修复当并发特性开启时onLoad不触发的问题。

  • 修复selector返回NaN时的警告。

  • 修复生成的许可证头部。

  • 添加package.json作为其中一个入口点。

  • 允许在挂起边界外挂起。

  • 当注水操作失败时记录一个可恢复的错误。

React DOM

  • 添加createRoothydrateRoot
  • 添加可选的注水操作。
  • 在已知ARIA属性列表中添加 aria-description
  • 添加onResize事件到video元素。
  • 添加imagesizeimageSrcSet到已知的属性中。
  • 如果提供了value,允许非字符串<option>children。
  • 修复aspectRatio样式未被应用。
  • 如果renderSubtreeIntoContainer被调用,则发出警告。

React DOM Server

  • 添加新的流渲染器。
  • 修复SSR中处理多个请求时的context providers。
  • 文本不匹配时回退到客户端渲染。
  • 废弃renderToNodeStream
  • 修复新服务器渲染器中的虚假错误日志。
  • 修复新服务器渲染器中的一个bug。
  • 忽略服务器上自定义元素中的函数和symbol值。

React DOM Test Utils

  • act在生产中使用时抛出。
  • 支持使用global.IS_REACT_ACT_ENVIRONMENT禁用虚假行为警告。
  • 扩展act warning以覆盖所有可能调度React工作的api。
  • 使act批量工作。
  • 移除dangling passive effects的警告。

React Refresh

  • 在快速刷新中跟踪late-mounted roots。
  • package.json中添加exports字段。

Server Components (实验性的)

  • 添加服务器上下文支持。
  • 添加lazy的支持。
  • 为webpack 5更新webpack插件。
  • 修复Node加载器中的一个错误。
  • 使用globalThis代替window作为边缘环境。

Artifacts


以上就是全部翻译内容,翻译的不好,请大家见谅。如有任何想法,欢迎评论交流。

小彩蛋:github.com/reactjs/rea…

❤️支持

如果本文对你有帮助,点赞👍支持下我吧,你的「赞」是我创作的动力。