React 生命周期钩子

概念---什么是生命周期钩子

React官方文档中说到:在组件类上声明特殊的方法,当组件挂载或卸载时,来运行一些代码,这些方法被称做生命周期钩子。html

生命周期图解

clipboard.png

在官方文档给出的组件生命周期的图中,咱们能够很清楚的认识到,一个React组件的生命周期主要分为3个阶段:建立时、更新时、卸载时。node

建立时阶段

当组件处于初始化阶段时,依次调用:react

  1. defaultProps(默认状态,通常用于若是父组件调用子组件的时候不给子组件传值,能够在子组件中使用defaultProps定义的默认值)
// defaultProps初始化props,只会调用一次
class Hello extends React.Component {
    static defaultProps = {
      name: 'Lily',
      age: 13
    }
    render: function(){
            return (
                <div>Hello,{this.props.name}</div>
            )
        }
}

注意: React.PropTypes 自 React v15.5 起已弃用,官方推荐使用使用prop-types代替npm

// 类型检测
import PropTypes from 'prop-types';

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

Greeting.propTypes = {
  name: PropTypes.string
};

  1. constructor
If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component.

The constructor for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.segmentfault


官方文档中描述到constructor只是是用来初始化状态和为实例绑定函数的,而且在组件挂载以前被调用。浏览器

class Hello extends React.Component {
  constructor(props) {
    // 
    super(props);
    // 此处不能够调用this.setState();
    this.state = {data: 'Hello world'};
  }

  render() {
    return (
      <div>
        <h1>{this.state.data}</h1>
      </div>
    );
  }
}

同时也要注意,this.state = { color: props.color };这种写法是不正确的。而且避免在constructor中声明介绍 side-effects(反作用) 或者 subscriptions(订阅)性能优化


3. componentWillMount(UNSAFE_componentWillMount())
componentWillMount发生在组件挂载以前 ,在render以前调用,所以在此方法中同步调用setState()不会触发额外的渲染。
componentWillMount也不能声明介绍 side-effects(反作用) 或者 subscriptions(订阅)网络


4. render
render()方法是惟一一个类组件必需的方法。当调用时会检查this.props 和 this.state,而后返回如下类型:less

  • React elements,相似于: <div /> ,<MyComponent />。
  • Arrays and fragments。Fragments可让你在不新增DOM节点的同时返回一个组件列表。
render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}
  • Portals。正常状况下,子组件挂载在最接近的父节点下,可是Portals能够将子级呈现到父组件的DOM层次结构以外的DOM节点中,ReactDOM.createPortal(child, container)包含两个参数:child---任意可渲染的 React 组件, container--- DOM节点。
render() {
  // React does *not* create a new div. It renders the children into `domNode`.
  // `domNode` is any valid DOM node, regardless of its location in the DOM.
  return ReactDOM.createPortal(
    this.props.children,
    domNode
  );
}
  • String 和 numbers。
  • Booleans 和 null。

render 是纯粹的, 不能在 render 方法中修改组件状态,同时 render 也不直接和浏览器交互。dom


5. componentDidMount
componentDidMount() 在组件挂载以后当即调用,能够在此处初始化须要的节点,也能够在此处调用服务和事件订阅。由于该方法被调用时,真实DOM已经被渲染,因此能够用来访问DOM节点,相似于Modal、tooltips等组件。官方文档建议尽可能不要在此方法内使用setState(),由于尽管用户不会看见中间状态,可是也可能引起性能问题。

更新时阶段

在更新时阶段,也能够说是运行时阶段,组件已经渲染完成,用户能够和组件进行交互,并触发状态改变,进入新的生命周期。
1. componentWillReceiveProps
在一个已经挂载完成的组件的收到一个新的props,将会调用componentWillReceiveProps方法去比较 this.propsnextProps 是否不同,而后this.setState()更新state。

componentWillReceiveProps(nextProps){
    if(nextProps.value === this.props.value){
        this.setState({...});
    }
}

2. shouldComponentUpdate
shouldComponentUpdate(),是生命周期的一个性能优化点,可以知道组件的输出是否不受当前状态或属性更改的影响。咱们能够在这个方法里经过返回 false 来阻止组件的从新渲染,返回 false 则不会执行 render ,componentWillUpdate,componentDidUpdate 方法。可是返回 false 不会阻止子组件在状态改变后从新渲染。

shouldComponentUpdate(nextProps, nextState){
    return true;
}

3. componentWillUpdate
componentWillUpdate 方法在组件接收到了新的props或者state即将从新渲染以前被调用。可是注意不能在此方法使用this.setState(),也不能在componentWillUpdate()方法返回以前进行其余可以更新React 组件的操做。

UNSAFE_componentWillUpdate(nextProps, nextState)


4. componentDidUpdate
componentDidUpdate(object prevProps, object prevState) 方法在组件从新被渲染以后会被调用,能够在这里操做 DOM和状态修改。在修改状态时,要注意setState() 方法要在条件嵌套中调用,不然会引发死循环。

componentDidUpdate(prevProps) {
  if (this.props.value !== prevProps.value) {
    this.fetchData(this.props.value);
  }
}

卸载时阶段

componentWillUnmount 方法在组件卸载和销毁以前被调用,能够在这个方法里执行清除。好比,定时器和事件订阅,以及撤销网络请求。

总结

组件生命周期

关于内容

React官方文档特别详述了生命周期钩子函数以及各个钩子函数的关系,我的建议从官方文档阅读总结。

关于文章

第一次写技术文章,可能不少地方写的不是很好,但愿你们多多指正,争取在下一篇,写的更好(这多是个flag)。

疑问

一、在官方文档中componentWillMount有一句描述,我的不是很理解:This is the only lifecycle method called on server rendering. 但愿有大佬能够为我答疑。

参考文章

React组件
React: 组件的生命周期

相关文章
相关标签/搜索