React 16 升级总结

一、前言
目前 React 最新的版本是 16.7.0,基于全新的 React Fiber 架构,有众多激动人心的新功能。由于是大版本升级,考虑到业务的稳定性,我们团队大概等了一年的时间,终于鼓起勇气着手升级的事情,特以此文来记录升级过程中遇到的坑。
二、升级的好处
这次升级的目标是将 React 从版本 15.6.2 升级到 16.2.0。原因是 16.2.0 为止引入了几个不错的新特性,同时对现有代码的影响会相对较小,风险可控。比较吸引我的三个新特性如下:
文件大小减少30%。官网原文如下:
react + react-dom is 109 kb (34.8 kb gzipped), down from 161.7 kb (49.8 kb gzipped).

Error Boundaries,可以将错误限制在可控范围,不会引起整个页面的白屏
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}

componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}

render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}

<ErrorBoundary>
<MyWidget />
</ErrorBoundary>

Fragments,可以在 render 返回多个一级组件,而不需要在外面包一个div

const Fragment = React.Fragment;

<Fragment>
<ChildA />
<ChildB />
<ChildC />
</Fragment>
三、升级遇到的问题
1、依赖项目中用到了 React Router 3 和 Redux。原计划将 Router 升级到 v4,但改动实在太大,放弃了,只是升级到支持 16 的版本。其它升级的依赖如下:
2、React.PropTypes这种写法已经不支持了,要改成:
// import { PropTypes } from ‘React’ 已废弃
import PropTypes from ‘prop-types’;
3、ReactDOM.render在生命周期函数里面,ReactDOM.render会返回null,因此类似下面这样的代码就会报错
function newInstance(props) {

let loading = ReactDOM.render(<Loading {…props} />, div);
return {
show: loading.show, // Error, loading 为 null
container: div,
};
}
4、setState(null) 不触发 render如果需要强制刷新的话,可以使用this.forceUpdate()
上述的问题主要是 16.0.0 带来的问题,更详尽的升级指南可以看这里的。
总结
总体来说,升级没有遇到特别大的困难,主要就是针对官方文档的Breaking changes部分,进行全局搜索,然后进行修改。另外,还有可能依赖的库用到了已经不支持的 API,例如PropTypes,应对办法就是升级对应的库。
先聊到这里,有其它疑问,欢迎留言交流。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理