参考链接:我对 React V16.4 生命周期的理解

废弃 UNSAFE_componentWillMount 的原因

有一个常见的问题,有人问为什么不在 UNSAFE_componentWillMount 中写 AJAX 获取数据的功能,他们的观点是,UNSAFE_componentWillMountrender 之前执行,早一点执行早得到结果。但是要知道,在 UNSAFE_componentWillMount 中发起 AJAX 请求,不管多快得到结果也赶不上首次 render,数据都是要在 render 后才能到达。
而且 UNSAFE_componentWillMount 在服务器端渲染也会被调用到(此方法是服务端渲染唯一会调用的生命周期函数。),你肯定不希望 AJAX 请求被执行多次,所以这样的 IO 操作放在 componentDidMount 中更合适。
尤其是在 Fiber 启用了异步渲染之后,更没有理由在 UNSAFE_componentWillMount 中进行 AJAX 请求了,因为 UNSAFE_componentWillMount 可能会被调用多次,谁也不会希望无谓地多次调用 AJAX 吧。
还有人会将事件监听器(或订阅)添加到 UNSAFE_componentWillMount 中,但这可能导致服务器渲染(永远不会调用 componentWillUnmount)和异步渲染(在渲染完成之前可能被中断,导致不调用 componentWillUnmount)的内存泄漏。
人们通常认为 UNSAFE_componentWillMountcomponentWillUnmount 是成对出现的,但这并不能保证。只有调用了 componentDidMount 之后,React 才能保证稍后调用 componentWillUnmount 进行清理。因此,添加监听器/订阅的推荐方法是使用 componentDidMount 生命周期。

废弃 UNSAFE_componentWillReceiveProps 的原因

有时候组件在 props 发生变化时会产生副作用。与 UNSAFE_componentWillUpdate 类似,UNSAFE_componentWillReceiveProps 可能在一次更新中被多次调用。因此,避免在此方法中产生副作用非常重要。相反,应该使用 componentDidUpdate,因为它保证每次更新只调用一次。
UNSAFE_componentWillReceiveProps 是考虑到因为父组件引发渲染可能要根据 props 更新 state 的需要而设立的。新的 getDerivedStateFromProps 实际上与 componentDidUpdate 一起取代了以前的 UNSAFE_componentWillReceiveProps 函数。

废弃 UNSAFE_componentWillUpdate 的原因

有些人使用 UNSAFE_componentWillUpdate 是出于一种错误的担心,即当 componentDidUpdate 触发时,更新其他组件的 state 已经”太晚”了。事实并非如此。React 可确保在用户看到更新的 UI 之前,刷新在 componentDidMountcomponentDidUpdate 期间发生的任何 setState 调用。
通常,最好避免这样的级联更新。当然在某些情况下,这些更新也是必需的(例如:如果你需要在测量渲染的 DOM 元素后,定位工具的提示)。不管怎样,在异步模式下使用 UNSAFE_componentWillUpdate 都是不安全的,因为外部回调可能会在一次更新中被多次调用。相反,应该使用 componentDidUpdate 生命周期,因为它保证每次更新只调用一次。
大多数开发者使用 UNSAFE_componentWillUpdate 的场景是配合 componentDidUpdate,分别获取 rerender 前后的视图状态,进行必要的处理。但随着 React 新的 suspensetime slicing异步渲染 等机制的到来,render 过程可以被分割成多次完成,还可以被暂停甚至回溯,这导致 UNSAFE_componentWillUpdatecomponentDidUpdate 执行前后可能会间隔很长时间,足够使用户进行交互操作更改当前组件的状态,这样可能会导致难以追踪的 BUG。
React 新增的 getSnapshotBeforeUpdate 方法就是为了解决上述问题,因为 getSnapshotBeforeUpdate 方法是在 UNSAFE_componentWillUpdate 后(如果存在的话),在 React 真正更改 DOM 前调用的,它获取到组件状态信息更加可靠。
除此之外,getSnapshotBeforeUpdate 还有一个十分明显的好处:它调用的结果会作为第三个参数传入 componentDidUpdate,避免了 UNSAFE_componentWillUpdatecomponentDidUpdate 配合使用时将组件临时的状态数据存在组件实例上浪费内存,getSnapshotBeforeUpdate 返回的数据在 componentDidUpdate 中用完即被销毁,效率更高。

分类: React 标签: 暂无标签

评论

暂无评论数据

暂无评论数据

目录