参考资料:
React:组件的生命周期
这个文档利用es5的creatClass,有些陈旧。需要研究两者差别的,移步
React 生命周期
这个过于粗暴,没有示例

一个React组件的生命周期分为三个部分:实例化、存在期和销毁时,如下图:

clipboard.png

实例化

  • getDefaultProps()
    设置默认的props,也可以用dufaultProps设置组件的默认属性.
  • getInitialState()
    在使用es6的class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state。
    每一个React组件都有自己的 state,其与 props 的区别在于 state只存在组件的内部,props 在所有实例中共享。
  • componentWillMount()
    组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。
  • render()
    react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
    只能通过 this.props 和 this.state 访问数据(不能修改),也就是不能调用this.setState()。
    只能出现一个顶级组件,不能返回一组元素。例如:

    render(){
        //这样不行
        this.setState({
         newState:_newState
        });
        return (
        <div></div>
        //去掉下面一行
        <div></div>
        );
    }
  • componentDidMount()
    组件渲染之后调用,只调用一次。

demo

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
class Clock extends Component{

    constructor(props){
        super(props);
        this.state = {
            date:new Date()
        }
    }

    //渲染前render执行
    componentWillMount(){
        //this.timer///////////////////////////
        this.timer =setInterval(()=>{
            this.setState({
                date: new Date()
            })
        },1000)
    }
    componentDidMount(){
        this.clock.focus();
    }
    componentWillUnmount(){
        clearInterval(this.timer)
    }
    render(){
        return(
            <div>
                <h1>
                    <p ref={(clock)=>this.clock=clock}>now time:</p>
                    {this.state.date.toLocaleTimeString()}
                </h1>
            </div>
        )
    }
}
ReactDOM.render(<Clock />, document.getElementById('root'));

存在期,更新操作改变

  • componentWillReceiveProps(nextProps)
    只有props改变时调用
  • shouldComponentUpdate(nextProps, nextState)
    react性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候
  • componentWillUpdata(nextProps, nextState)
    组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state。
  • render()
  • componentDidUpdate()
    组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。

demo

import React from 'react';
import ReactDOM from 'react-dom';
class Content extends React.Component {
    constructor(){
        super();
        this.state = {
            test:0
        }
    }
    componentWillMount() {
        console.log('Component WILL MOUNT!')
    }
    componentDidMount() {
        console.log('Component DID MOUNT!')
    }
    componentWillReceiveProps(newProps) {
        console.log(newProps)
        console.log('Component WILL RECEIVE PROPS!')
    }
    shouldComponentUpdate(newProps, newState) {
        console.log(newProps,newState)
        return true;
    }
    componentWillUpdate(nextProps, nextState) {
        console.log(nextProps,nextState)
        console.log('Component WILL UPDATE!');
    }
    componentDidUpdate(prevProps, prevState) {
        console.log(prevProps,prevState)
        console.log('Component DID UPDATE!')
    }
    componentWillUnmount() {
        console.log('Component WILL UNMOUNT!')
    }
    _handleClick(){
        this.setState({
            test:this.state.test + 1
        })
    }
    render() {
        return (
            <div>
                <h3>{this.props.myNumber}</h3>
                <label onClick={this._handleClick.bind(this)}>点我</label>
                <span>{this.state.test}</span>
            </div>
        );
    }
}

class Button extends React.Component {
    constructor(props) {
        super(props);
        this.state = {data: 0};
        this.setNewNumber = this.setNewNumber.bind(this);
    }

    setNewNumber() {
        this.setState({data: this.state.data + 1})
    }
    render() {
        return (
            <div>
            <button onClick = {this.setNewNumber}>INCREMENT</button>
            <Content myNumber = {this.state.data}></Content>
            </div>
    );
    }
}
ReactDOM.render(<Button />, document.getElementById('root'));

卸载

  • componentWillUnmount()
    组件将要卸载时调用,一些事件监听和定时器需要在此时清除,主要是优化性能,例子见Clock。

zeronlee
112 声望13 粉丝