一年多来,React团队一直致力于实现异步渲染。上个月,他在JSConf冰岛的演讲中,丹揭示了一些令人兴奋的新的异步渲染可能性。现在,我们希望与您分享我们在学习这些功能时学到的一些经验教训,以及一些帮助您准备组件以在启动时进行异步渲染的方法。
我们了解到的最大问题之一是,我们的一些传统组件生命周期会导致一些不安全的编码实践。他们是:
componentWillMount
componentWillReceiveProps
componentWillUpdate
这些生命周期方法经常被误解和滥用;此外,我们预计他们的潜在滥用可能在异步渲染方面有更大的问题。因此,我们将在即将发布的版本中为这些生命周期添加一个“UNSAFE_”前缀。 (这里,“不安全”不是指安全性,而是表示使用这些生命周期的代码将更有可能在未来的React版本中存在缺陷,特别是一旦启用了异步渲染)。
逐步迁移路径
React遵循语义版本控制, 所以这种改变将是渐进的。我们目前的计划是:
- 16.3:为不安全生命周期引入别名UNSAFE_componentWillMount,UNSAFE_componentWillReceiveProps和UNSAFE_componentWillUpdate。 (旧的生命周期名称和新的别名都可以在此版本中使用。)
- 未来的16.x版本:为componentWillMount,componentWillReceiveProps和componentWillUpdate启用弃用警告。 (旧的生命周期名称和新的别名都可以在此版本中使用,但旧名称会记录DEV模式警告。)
- 17.0:删除componentWillMount,componentWillReceiveProps和componentWillUpdate。 (从现在开始,只有新的“UNSAFE_”生命周期名称将起作用。)
请注意,如果您是React应用程序开发人员,那么您不必对遗留方法进行任何操作。即将发布的16.3版本的主要目的是让开源项目维护人员在任何弃用警告之前更新其库。这些警告将在未来的16.x版本发布之前不会启用。
我们在Facebook上维护了超过50,000个React组件,我们不打算立即重写它们。我们知道迁移需要时间。我们将采用逐步迁移路径以及React社区中的所有人。
从传统生命周期迁移
如果您想开始使用React 16.3中引入的新组件API(或者如果您是维护人员提前更新库),以下是一些示例,我们希望这些示例可以帮助您开始考虑组件的变化。随着时间的推移,我们计划在文档中添加额外的“配方”,以展示如何以避免有问题的生命周期的方式执行常见任务。
在开始之前,我们将简要概述为16.3版计划的生命周期更改:
- We are adding the following lifecycle aliases:
UNSAFE_componentWillMount
,UNSAFE_componentWillReceiveProps
, andUNSAFE_componentWillUpdate
. (Both the old lifecycle names and the new aliases will be supported.) -
We are introducing two new lifecycles, static
getDerivedStateFromProps
andgetSnapshotBeforeUpdate
. -
我们正在添加以下生命周期别名:
(1) UNSAFE_componentWillMount,
(2) UNSAFE_componentWillReceiveProps
(3) UNSAFE_componentWillUpdate。 (旧的生命周期名称和新的别名都将受支持。)
- 我们介绍了两个新的生命周期,分别是getDerivedStateFromProps和getSnapshotBeforeUpdate。
新的生命周期: getDerivedStateFromProps
class Example extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
// ...
}
}
新的静态getDerivedStateFromProps
生命周期在组件实例化以及接收新props
后调用。它可以返回一个对象来更新state
,或者返回null来表示新的props
不需要任何state
更新。
与componentDidUpdate
一起,这个新的生命周期应该覆盖传统componentWillReceiveProps
的所有用例。
新的生命周期: getSnapshotBeforeUpdate
class Example extends React.Component {
getSnapshotBeforeUpdate(prevProps, prevState) {
// ...
}
}
新的getSnapshotBeforeUpdate
生命周期在更新之前被调用(例如,在DOM被更新之前)。此生命周期的返回值将作为第三个参数传递给componentDidUpdate
。 (这个生命周期不是经常需要的,但可以用于在恢复期间手动保存滚动位置的情况。)
与componentDidUpdate
一起,这个新的生命周期将覆盖旧版componentWillUpdate
的所有用例。
兼容旧版本
当React 16.3发布时,我们还将发布一个新的npm包, react-lifecycles-compat
。该npm包会填充组件,以便新的getDerivedStateFromProps
和getSnapshotBeforeUpdate
生命周期也可以与旧版本的React(0.14.9+)一起使用。
要使用这个polyfill,首先将它作为依赖项添加到您的库中:
# Yarn
yarn add react-lifecycles-compat
# NPM
npm install react-lifecycles-compat --save
接下来,更新您的组件以使用新的生命周期(如上所述)。
最后,使用polyfill将组件向后兼容旧版本的React:
import React from 'react';
import {polyfill} from 'react-lifecycles-compat';
class ExampleComponent extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
// Your state update logic here ...
}
}
// Polyfill your component to work with older versions of React:
polyfill(ExampleComponent);
export default ExampleComponent;
原文请参考: