13
2019年8月8日,我们发布了React 16.9。它包含几个新功能,错误修正和新的弃用警告,以帮助准备未来的主要版本。

clipboard.png

新的版本:

重命名不安全的生命周期方法

一年多以前,我们宣布重新命名不安全的生命周期方法:

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前端交流群~

目前人数太多,只能我邀请入群了哦~

clipboard.png


PeterTan
14.4k 声望30k 粉丝