Post

React 16 对比 15 的变更和要注意的点

React 16 对比 15 的变更和要注意的点

React 16 核心变更

1. Fiber 架构:更高效的更新机制

React 16 的核心变更是引入了 Fiber 架构,它完全重写了 React 的 Reconciler(协调器),主要带来了以下优势:

  • 异步渲染:渲染任务可被打断,提高高优先级任务的响应速度。
  • 更细粒度的更新:组件更新拆分成小任务,避免长时间阻塞主线程。

2. 生命周期方法的调整

React 16 废弃了一些生命周期方法,并引入了新的替代方案。

React 15 生命周期React 16 变更
componentWillMountconstructorcomponentDidMount 替代
componentWillReceivePropsgetDerivedStateFromProps 替代
componentWillUpdategetSnapshotBeforeUpdate 替代

影响:

  1. 如果你的代码依赖 componentWillReceiveProps 处理 props 变化,请使用 getDerivedStateFromProps
  2. 如果你在 componentWillUpdate 里获取 DOM 快照,请改用 getSnapshotBeforeUpdate
  3. 如果你在 componentWillMount 里做副作用操作(如 API 请求),请改到 componentDidMount

示例getDerivedStateFromProps):

1
2
3
4
5
6
7
8
class MyComponent extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.value !== prevState.value) {
      return { value: nextProps.value };
    }
    return null;
  }
}

3. Error Boundaries(错误边界)

React 16 允许我们使用 Error Boundaries 来捕获子组件的错误,防止整个应用崩溃。

** 新增方法:**

  • componentDidCatch(error, info)
  • static getDerivedStateFromError(error)

示例(错误边界组件):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error("Caught error: ", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>发生错误</h1>;
    }
    return this.props.children;
  }
}

注意点:错误边界 只能捕获子组件的渲染错误,但不会捕获 事件处理器、异步代码(如 setTimeout)、服务端渲染(SSR)等错误。


其他新特性与优化

1. React Portals(跨层级渲染)

在 React 15 中,组件的渲染层级受限于组件树,而在 React 16 中,可以使用 ReactDOM.createPortal 将组件渲染到任意 DOM 位置。

示例(创建 Modal 组件):

1
2
3
4
ReactDOM.createPortal(
  <div className="modal">Hello Portal</div>,
  document.getElementById("modal-root")
);

常用场景:模态框、全屏弹窗等。


2. 服务器端渲染(SSR)优化

React 16 提供了 renderToNodeStream,相较于 React 15 的 renderToString,可以 流式渲染 HTML,提高 SSR 性能。

示例(SSR 流式渲染):

1
2
const stream = ReactDOMServer.renderToNodeStream(<App />);
stream.pipe(res);
This post is licensed under CC BY 4.0 by the author.