React Component(生命周期)

RN 组件的生命周期以下图:html

 

生命周期回调函数

挂载

当组件实例被建立并插入 DOM 中时,其生命周期调用顺序以下:react

注意:api

下述生命周期方法即将过期,在新代码中应该避免使用它们数组

更新

当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序以下:浏览器

注意:网络

下述方法即将过期,在新代码中应该避免使用它们async

卸载

当组件从 DOM 中移除时会调用以下方法:函数

错误处理

当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用以下方法:性能

 

经常使用的生命周期方法

一、render()

render() 方法是 class 组件中惟一必须实现的方法。fetch

当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回如下类型之一:

  • React 元素。一般经过 JSX 建立。例如,<div /> 会被 React 渲染为 DOM 节点,<MyComponent /> 会被 React 渲染为自定义组件,不管是 <div /> 仍是 <MyComponent /> 均为 React 元素。
  • 数组或 fragments。 使得 render 方法能够返回多个元素。。
  • Portals。能够渲染子节点到不一样的 DOM 子树中。
  • 字符串或数值类型。它们在 DOM 中会被渲染为文本节点
  • 布尔类型或 null。什么都不渲染。(主要用于支持返回 test && <Child /> 的模式,其中 test 为布尔类型。)

render() 函数应该为纯函数,这意味着在不修改组件 state 的状况下,每次调用时都返回相同的结果,而且它不会直接与浏览器交互。

如需与浏览器进行交互,请在 componentDidMount() 或其余生命周期方法中执行你的操做。保持 render() 为纯函数,可使组件更容易思考。

注意

若是 shouldComponentUpdate() 返回 false,则不会调用 render()

二、constructor()

若是不初始化 state 或不进行方法绑定,则不须要为 React 组件实现构造函数。

在 React 组件挂载以前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其余语句以前前调用 super(props)。不然,this.props 在构造函数中可能会出现未定义的 bug。

一般,在 React 中,构造函数仅用于如下两种状况:

在 constructor() 函数中不要调用 setState() 方法。若是你的组件须要使用内部 state,请直接在构造函数中为 this.state 赋值初始 state。

要避免在构造函数中引入任何反作用或订阅。如遇到此场景,请将对应的操做放置在 componentDidMount 中

 

三、componentDidMount()

componentDidMount() 会在组件挂载后(插入 DOM 树中)当即调用。依赖于 DOM 节点的初始化应该放在这里。如需经过网络请求获取数据,此处是实例化请求的好地方

这个方法是比较适合添加订阅的地方。若是添加了订阅,请不要忘记在 componentWillUnmount() 里取消订阅

能够在 componentDidMount() 里直接调用 setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕以前。如此保证了即便在 render() 两次调用的状况下,用户也不会看到中间状态。请谨慎使用该模式,由于它会致使性能问题。一般,你应该在 constructor() 中初始化 state。若是你的渲染依赖于 DOM 节点的大小或位置,好比实现 modals 和 tooltips 等状况下,你可使用此方式处理

 

四、componentDidUpdate()

componentDidUpdate() 会在更新后会被当即调用。首次渲染不会执行此方法。

当组件更新后,能够在此处对 DOM 进行操做。若是你对更新先后的 props 进行了比较,也能够选择在此处进行网络请求。

componentDidUpdate(prevProps) {
  // 典型用法(不要忘记比较 props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

 

你也能够在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,不然会致使死循环。它还会致使额外的从新渲染,虽然用户不可见,但会影响组件性能。不要将 props “镜像”给 state,请考虑直接使用 props

 

五、componentWillUnmount()

componentWillUnmount() 会在组件卸载及销毁以前直接调用。在此方法中执行必要的清理操做,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中建立的订阅等。

componentWillUnmount() 中不该调用 setState(),由于该组件将永远不会从新渲染。组件实例卸载后,将永远不会再挂载它。

 

不经常使用的生命周期方法

并不太经常使用。它们偶尔会很方便,可是大部分状况下组件可能都不须要它们。

 

一、shouldComponentUpdate()

根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会从新渲染。

 

二、static getDerivedStateFromProps()

getDerivedStateFromProps 会在调用 render 方法以前调用,而且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,若是返回 null 则不更新任何内容。

此方法适用于 state 的值在任什么时候候都取决于 props。

派生状态会致使代码冗余,并使组件难以维护。 确保你已熟悉这些简单的替代方案:

三、getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)以前调用。它使得组件能在发生更改以前从 DOM 中捕获一些信息(例如,滚动位置)。今生命周期的任何返回值将做为参数传递给 componentDidUpdate()

此用法并不常见,但它可能出如今 UI 处理中,如须要以特殊方式处理滚动位置的聊天线程等。

应返回 snapshot 的值(或 null)。

 

Error boundaries

Error boundaries 是 React 组件,它会在其子组件树中的任何位置捕获 JavaScript 错误,并记录这些错误,展现降级 UI 而不是崩溃的组件树。Error boundaries 组件会捕获在渲染期间,在生命周期方法以及其整个树的构造函数中发生的错误。

若是 class 组件定义了生命周期方法 static getDerivedStateFromError() 或 componentDidCatch() 中的任何一个(或二者),它就成为了 Error boundaries。经过生命周期更新 state 可以让组件捕获树中未处理的 JavaScript 错误并展现降级 UI。

仅使用 Error boundaries 组件来从意外异常中恢复的状况;不要将它们用于流程控制。

欲了解更多详细信息,请参阅 React 16 中的错误处理

注意

Error boundaries 仅捕获组件树中如下组件中的错误。但它自己的错误没法捕获。

相关文章
相关标签/搜索