2019 年 8 月 8 日,我们发布了 React 16.9。它包含几个新功能,错误修正和新的弃用警告,以帮助准备未来的主要版本。
新的版本:
重命名不安全的生命周期方法
一年多以前,我们宣布重新命名不安全的生命周期方法:
componentWillMount → UNSAFE_componentWillMount
componentWillReceiveProps → UNSAFE_componentWillReceiveProps
componentWillUpdate → UNSAFE_componentWillUpdate
React 16.9 不包含重大更改,旧版本名称在此版本中继续有效。但是,当您使用任何旧名称时,您将看到警告:
警告:componentWillMount 已重命名,不建议使用。
正如警告所示,每种不安全方法通常都有更好的方法。但是,您可能没有时间迁移或测试这些组件。在这种情况下,我们建议运行一个“codemod”脚本,自动重命名它们:
npx react-codemod rename-unsafe-lifecycles
(注意它说 npx,不是 npm。npx 默认情况下是 Node 6+ 附带的实用程序。)
运行此 codemod
将替换旧名称,如 componentWillMount
新名称,如UNSAFE_componentWillMount
:
Codemod
在行动
新的名字 UNSAFE_componentWillMount
将继续在 React 16.9 和 React 17.x 中运行。但是,新的 UNSAFE_前缀将帮助具有问题模式的组件在代码审查和调试会话期间脱颖而出。(如果您愿意,可以通过选择严格模式进一步阻止他们在您的应用中使用。)
注意
详细了解我们的版本政策和对稳定性的承诺。
弃用 javascript:
网址
以 … 开头的 URL javascript: 是一个危险的攻击面,因为它很容易在标签中意外包含未经过类型化的输出 a
标签,并创建一个安全漏洞:
const userProfile = {website: "javascript: alert('you got hacked')",
};
// This will now warn:
<a href={userProfile.website}>Profile</a>
在 React 16.9 中,此模式继续有效,但它将记录警告。如果您使用 javascript:URL 作为逻辑,请尝试使用 React 事件处理程序。(作为最后的手段,你可以绕过保护 dangerouslySetInnerHTML,但是它非常气馁并经常导致安全漏洞。)
在未来的主要版本中,如果遇到javascript:URL
,React 将抛出错误。
弃用“工厂”组件
在使用 Babel 编译 JavaScript 类之前变得流行之前,React 支持使用 render 方法返回对象的“工厂”组件:
function FactoryComponent() {return { render() {return <div />;} }
}
这种模式令人困惑,因为它看起来太像一个功能组件 – 但它不是一个。(函数组件只会 <div /> 在上面的例子中返回。)
这种模式几乎从未在野外使用,并且支持它会导致 React 略大且比必要的慢。因此,我们在 16.9 中弃用此模式,并在遇到警告时记录警告。如果您依赖它,添加 FactoryComponent.prototype = React.Component.prototype
可以作为一种解决方法。或者,您可以将其转换为类或函数组件。
我们不希望大多数代码库受此影响。
新功能
异步 act()测试
React 16.8 引入了一个新的测试实用程序,act()用于帮助您编写更符合浏览器行为的测试。例如,一次 act()获取批量内的多个状态更新。这与 React 在处理真实浏览器事件时的工作方式相匹配,并有助于为将来 React 将更频繁地批量更新的组件做好准备。
但是,在 16.8 中 act()仅支持同步功能。有时,您可能在测试中看到过类似的警告但无法轻松修复它:
An update to SomeComponent inside a test was not wrapped in act(...).
在 React 16.9 中,act()也接受异步函数,你可以 await 调用它:
await act(async () => {// ...});
这解决了 act()以前无法使用的其余情况,例如状态更新在异步函数内部时。因此,您应该能够立即修复 act()测试中的所有剩余警告。
我们听说没有足够的信息来说明如何编写测试 act()。新的“测试食谱”指南介绍了常见的场景,以及如何 act()帮助您编写好的测试。这些示例使用 vanilla DOM API,但您也可以使用 React Testing Library 来减少样板代码。它的许多方法已在 act()内部使用。
如果您碰到任何其他不适合您的情况,请告知我们问题跟踪器 act(),我们会尽力提供帮助。
性能测量 <React.Profiler>
在 React 16.5 中,我们为 DevTools 引入了一个新的React Profiler
,它可以帮助您找到应用程序中的性能瓶颈。在 React 16.9 中,我们还添加了一种编程方式来收集所谓的测量 <React.Profiler>。我们预计大多数较小的应用都不会使用它,但在较大的应用中跟踪性能回归可能很方便。
该 <Profiler>
如何往往是一个作出反应的应用程序呈现什么渲染的“成本”的措施。其目的是帮助识别应用程序的某些部分,这些部分很慢并且可能会受益于优化(如 memoization)。
<Profiler> 可以在 React 树中的任何位置添加 A 来测量渲染树的该部分的成本。它需要两个道具:一个 id(字符串)和一个 onRender 回调(函数),当树中的一个组件“提交”更新时,它会调用它。
render(<Profiler id="application" onRender={onRenderCallback}>
<App>
<Navigation {...props} />
<Main {...props} />
</App>
</Profiler>
);
要了解更多有关 Profiler 并传递给参数 onRender 回调,检查出的 Profiler 文档。
注意:
分析会增加一些额外的开销,因此在生产构建中禁用它。
为了选择生产分析,React 提供了一个特殊的生产构建,并启用了分析。阅读有关如何在 fb.me/react-profiling 中使用此构建的更多信息。
值得注意的错误修正
此版本包含一些其他显着的改进:
修复 findDOMNode() 了在 <Suspense>
树内调用时崩溃的问题。
保留删除的子树导致的内存泄漏也已得到修复。
由 setStatein 引起的无限循环 useEffect 现在记录错误。(这类似于你看,当你调用错误 setState 中 componentDidUpdate 的一类。)
我们感谢所有帮助解决这些问题和其他问题的贡献者。您可以在下面找到完整的更改日志。
路线图的更新
在 2018 年 11 月,我们发布了 16.x 版本的路线图:
带有 React Hooks 的小型 16.x 版本(过去估计:2019 年第一季度)
带有并发模式的小型 16.x 版本(过去的估计:2019 年第二季度)
带有 Suspense for Data Fetching 的未成年人 16.x 版本(过去估计:2019 年中)
这些估计太乐观了,我们需要调整它们。
tldr:我们按时发布了 Hooks,但我们正在将 Concurrent Mode 和 Suspense for Data Fetching 重新组合成一个我们打算在今年晚些时候发布的版本。
2 月份,我们发布了一个稳定的 16.8 版本,包括 React Hooks,一个月后 React Native 支持。但是,我们低估了此版本的后续工作,包括 lint 规则,开发人员工具,示例和更多文档。这使时间线改变了几个月。
现在 React Hooks 已经推出,并行模式和数据提取的悬念工作正在全面展开。目前正在积极开发的新 Facebook 网站建立在这些功能之上。使用真实代码对它们进行测试有助于在影响开源用户之前发现并解决许多问题。其中一些修复涉及这些功能的内部重新设计,这也导致时间线滑落。
有了这种新的理解,这就是我们计划下一步做的事情。
一个发行而不是两个
Concurrent Mode 和 Suspense 为正在积极开发的新 Facebook 网站提供支持,因此我们有信心他们在技术上接近稳定状态。我们现在也更好地了解了它们为开源采用做好准备之前的具体步骤。
最初我们认为我们会将 Concurrent Mode 和 Suspense for Data Fetching 分成两个版本。我们发现这种排序很难解释,因为这些特征与我们最初想到的相关性更大。因此,我们计划在单个组合版本中发布对 Concurrent Mode 和 Suspense for Data Fetching 的支持。
我们不希望再次过度推销发布日期。鉴于我们在生产代码中依赖于它们,我们希望今年能够提供 16.x 版本,并为其提供选择支持。
数据提取的更新
虽然 React 并未就如何获取数据发表意见,但数据提取的 Suspense 的第一个版本可能会专注于与固定数据提取库集成。例如,在 Facebook,我们正在使用与 Suspense 集成的即将推出的 Relay API。我们将记录像 Apollo 这样的其他自以为是的图书馆如何支持类似的整合。
在第一个版本中,我们不打算关注我们在早期演示中使用的临时“触发 HTTP 请求”解决方案(也称为“React Cache”)。但是,我们希望我们和 React 社区将在首次发布后的几个月内探索该空间。
服务器渲染的更新
我们已经开始研究新的支持 Suspense 的服务器渲染器,但是我们不希望它为初始版本的并发模式做好准备。但是,此版本将提供一个临时解决方案,允许现有服务器呈现器立即为 Suspense 回退发出 HTML,然后在客户端上呈现其真实内容。这是我们目前在 Facebook 上使用的解决方案,直到流式渲染器准备就绪。
为什么需要这么长时间?
我们已经发布了导致 Concurrent Mode 稳定的各个部分,包括新的上下文 API,延迟加载 Suspense 和 Hooks。我们也急于释放其他缺失的部分,但是大规模地尝试它们是该过程的重要部分。诚实的回答是,当我们开始时,它只需要比我们预期的更多的工作。与往常一样,我们感谢您在 Twitter 和我们的问题跟踪器中提出的问题和反馈。
安装
应对
Npm 注册表中提供了 React v16.9.0。
要使用 Yarn 安装 React 16,请运行:
yarn add react@^16.9.0 react-dom@^16.9.0
要使用 npm 安装 React 16,请运行:
npm install –save react@^16.9.0 react-dom@^16.9.0
我们还通过 CDN 提供了反应的 UMD 版本:
<script crossorigin src=”https://unpkg.com/react@16/um…;></script>
<script crossorigin src=”https://unpkg.com/react-dom@1…;></script>
有关详细的安装说明,请参阅文档。
更新日志
应对
添加 <React.Profiler>API 以编程方式收集性能测量。(@bvaughn 在#15172)
删除 unstable_ConcurrentMode 赞成 unstable_createRoot。(@acdlite 在#15532)
反应 DOM
弃用 UNSAFE_* 生命周期方法的旧名称。(@bvaughn 在#15186 和 @threepointone 在#16103)
将 javascript:URL 弃用为常见攻击面。(@sebmarkbage 在#15047)
弃用不常见的“模块模式”(工厂)组件。(@sebmarkbage 在#15145)
添加对 disablePictureInPicture 属性的支持 <video>。(@eek in #15334)
添加对 onLoad 事件的支持 <embed>。(@cherniavskii 在#15614)
useState 从 DevTools 添加对编辑状态的支持。(@bvaughn 在#14906)
添加对从 DevTools 切换 Suspense 的支持。(@gaeon 在#15232)
setState 从调用时发出警告 useEffect,创建循环。(@gaeon 在#15180)
修复内存泄漏。(@paulshen in #16115)
修复包含在其中 findDOMNode 的组件的内部崩溃 <Suspense>。(@acdlite 在#15312)
修复因刷新太晚而导致的待处理效果。(@acdlite 在#15650)
修复警告消息中不正确的参数顺序。(@brickspert 在#15345)
修复了存在!important 样式时隐藏悬疑后备节点的问题。(@acdlite 在#15861 和#15882)
略微提高保湿性能。(@bmeurer 在#15998)
反应 DOM 服务器
修复 camelCase 自定义 CSS 属性名称的错误输出。(@bedakb 在#16167)
反应测试实用程序和测试渲染器
添加 act(async () => …)用于测试异步状态更新。(#14853 中的 @threepointone)
添加对 act 不同渲染器的嵌套的支持。(@threepointone 在#16039 和#16042)
如果在 act()通话外安排效果,请在严格模式下警告。(@threepointone 在#15763 和#16041)
act 从错误的渲染器使用时发出警告。(@threepointone 在#15756)
编辑这个页面
欢迎加入我们的
SegmentFault
前端交流群~
目前人数太多,只能我邀请入群了哦~