React 16 更新一览

8,006 阅读3分钟

就在今天,React 团队正式发布了 React 16,这次发布带来了哪些内容呢?

全新的内部架构

  • React 16 采用了称为“Fiber”的全新的内部架构。官方对 Fiber 的一句话解释是“React Fiber是对核心算法的一次重新实现”。
  • 以前的 React 使用的称为“Stack”的更新方式下,一个调用链很长并且计算量很大的任务的调用栈会如下图:
    v2-d8f4598c70df94d69825f11dfbf2ca2c_b--1-
  • 通过“Fiber”,React 使得大量的计算可以被拆解分片,异步化。每执行完一段更新过程,就把控制权交还给React负责任务协调的模块,看看有没有其他紧急任务要做。从而保证了渲染的帧率,提高应用响应性。下图中每一个波谷代表深入某个分片的执行过程,每个波峰就是一个分片执行结束交还控制权的时机:
    v2-78011f3365ab4e0b6184e1e9201136d0_b-1
  • 在今年早些的 React Conf 上,React 开发者介绍了 Fiber 的工作原理和实际效果。在演示 Demo 中,一个非常深的组件树在使用 Fiber 前后的渲染帧率有了非常大的提升(视频 3:30 左右)。

新增了一个顶级 API: ReactDOM.createPortal

  • Portal 本身不是新的概念,在以往使用 React 实现模态框等组件时我们也会用到,现在 React 官方提供了 API 使得能够更方便地实现这样的功能。
  • 在一般的 React 结构中,组件的嵌套关系和渲染出来的 DOM 的嵌套关系是一致的(子组件渲染出的 DOM 一定是在父组件渲染出的 DOM 的内部的)。
  • 但某些情况下,这样的限制会导致问题,例如实现一个模态框(Modal),虽然模态框所在的组件在它的父组件内部,但是通常需要被渲染在 body 元素下。 新的 API 使用方式如下:
render() {
  // React 会在你提供的 domNode 下渲染,而不是在当前组件所在的 DOM
  return ReactDOM.createPortal(
    this.props.children,
    domNode,
  );
}
  • 更多信息可以查看 Portals

render 方法能够返回数组了

  • 在以前,一个组件的 render 方法中如果要返回多个 element,必须使用一个元素将它们包裹起来。这样可能会导致很多不必要的嵌套。
  • 现在你可以这样写了:
render() {
  // 不需要再包裹一层了!
  return [
    // 但是要使用 key
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}
  • 还支持了只返回一个字符串:
render() {
  return 'Look ma, no spans!';
}

更好的错误处理

  • 在以前,如果 React 在运行时遇到错误会导致应用崩溃(和一般的 JavaScript 运行时错误一样,之后的代码不会执行了)。
  • 现在 React 给组件增加了 componentDidCatch(error, info) 的生命周期函数,你可以定义组件的错误处理函数,这样组件在遇到运行时错误时会像增加了 try...catch 一样,不会将错误直接抛出了,错误被局部组件 catch 住,保证了整个应用的可用性。
  • 同时,React 还提供了更友好的错误提示,帮助开发者更好地发现问题。
  • 详细可以查看 Error Handling in React 16

更小的体积

  • React 16 下, react + react-dom 在 gizp 后的总体积为 109KB,比之前版本的 161.7KB 减小了 30%。

部分非核心模块被移出

  • React.createClassReact.PropTypes 等模块被移出了 react 包,现在你必须从单独的包里引入。

基于 MIT 协议

  • 现在 React 15.6.2 和 React 16 都是基于 MIT 协议了,你可以自由选择。

完整更新日志请查看React v16.0