Skip to content

React组件生命周期 #12

Open
Open
@andyChenAn

Description

@andyChenAn

react组件生命周期(16以上版本)

React组件的生命周期可以分为三个过程:

  • 挂载过程(Mount):第一次把组件挂载到DOM树上。
  • 更新过程(Update):组件渲染更新的过程。
  • 卸载过程(Unmount):组件从DOM树删除的过程。

挂载过程

1、首先调用constructor,进行组件初始化操作,一般会在这里进行组件state初始化,以及绑定成员函数的this(这里我们也可以直接使用箭头函数,这样就不需要绑定在constructor里面绑定this了)

class App extends Component {
	constructor (props) {
		super(props);
		// 这里进行组件state初始化操作
		this.state = {
			name : 'andy'
		}
		// 绑定成员函数this
		this.handleClick = this.handleClick.bind(this);
	}
	handleClick () {
		this.setState({
			name : 'jack'
		});
	}
	render () {
		const { name } = this.state;
		return (
			<div>
				<button onClick={this.handleClick}>click here</button>
				<div>{name}</div>
			</div>
		)
	}
}

2、调用componentWillMount函数。
3、调用render函数来渲染组件,这个函数一定会有一个返回值,返回的是一个React元素或者null。这里仅仅只是返回一个React元素,并没有将组件挂载到DOM树上。一般我们在这里可以通过this.state和this.props来控制返回的React元素。

4、调用componentDidMount函数,这个函数会在组件被挂载到DOM树之后调用。一般我们会在这里通过请求来获取数据和绑定事件监听函数。

class App extends Component {
	constructor (props) {
		super();
		console.log(props);
		// 这里进行组件state初始化操作
		this.state = {
			name : 'andy'
		}
		// 绑定成员函数this
		this.handleClick = this.handleClick.bind(this);
	}
	handleClick () {
		this.setState({
			name : 'jack'
		});
	}
	componentDidMount () {
		// 发送请求获取数据
		axios.get('xxx')
		.then(res => {

		})
		.catch(err => {

		})
	}
	render () {
		const { name } = this.state;
		return (
			<div>
				<button onClick={this.handleClick}>click here</button>
				<div>{name}</div>
			</div>
		)
	}
}

更新过程

我们通过修改组件的props和state来更新组件。更新过程会触发以下声明周期函数:

1、当props改变时,会触发componentWillReceiveProps函数。

2、会调用shouldComponentUpdate(nextProps , nextState)函数,这个函数接受两个参数,一个是改变后的props,一个是改变后的state,调用该返回必须返回一个布尔值,如果是false,表示不需要重新渲染组件(不会调用render函数),如果是true,表示需要重新渲染组件(会调用render函数)。一般会在这里进行优化。

class Button extends Component {
    constructor (props) {
        super(props);
        this.state = {
            tick : 0
        };
        console.log("组件初始化");
    }
    onClickHandle () {
        this.setState({
            tick : ++this.state.tick
        });
        this.props.onHandleClick();
    }
    shouldComponentUpdate (nextProps , nextState) {
        console.log('组件是否需要更新');
        // 通过返回值来表示组件是否需要重新渲染
        return true;
    }
    componentDidUpdate () {
        console.log('组件已经更新');
    }
    componentDidMount () {
        console.log('组件已经挂载');
    }
    render () {
        console.log('渲染');
        const { color } = this.props;
        return <button onClick={() => this.onClickHandle()} style={{color : `${color}`}}>{this.state.tick}</button>
    }
}

class App extends Component {
    constructor (props) {
        super(props);
        this.state = {
            color : 'black'
        }
    }
    handleClick = () => {
        this.setState({
            color : 'red'
        })
    }
    render () {
        return (
            <div>
                <h1>hello andy</h1>
                <h1 style={{color : 'red'}}>hello peter</h1>
                <Button onHandleClick={this.handleClick} color={this.state.color} name="点我" />
            </div>
        )
    }
}

上面的shouldComponentUpdate函数中,如果返回false,那么当我们点击按钮时,不会加1,因为不会调用render函数进行重新渲染,并且也不会触发componentDidUpdate函数,如果返回true,那么点击按钮时,会加1。

3、如果shouldComponentUpdate函数返回true,那么会调用componentWillUpdate函数。

4、调用render函数,进行渲染。这个地方会重新创建react元素,并绑定最新的props和state。

class App extends Component {
    constructor (props) {
        super(props);
        this.state = {
            tick : 0
        };
        console.log("组件初始化");
    }
    onClickHandle () {
        this.setState({
            tick : ++this.state.tick
        });
    }
    shouldComponentUpdate (nextProps , nextState) {
        console.log('组件是否需要更新');
        return true;
    }
    componentDidUpdate () {
        console.log('组件已经更新');
    }
    componentDidMount () {
        console.log('组件已经挂载');
    }
    render () {
        console.log('渲染');
        // 这里获取的是最新的state
        console.log(this.state);
        return <button onClick={() => this.onClickHandle()}>{this.state.tick}</button>
    }
}

5、会调用componentDidUpdate函数,这个函数表示React组件已经更新完成了。

卸载过程

当我们不需要一个组件时,我们可以把组件从DOM树上删除,在删除前的这个时候会触发componentWillUnmount函数。在这个函数我们一般会去解绑事件,删除定时器,或者其他一些没有用的变量等,主要是为了防止内存泄漏。

class Button extends Component {
    constructor (props) {
        super(props);
        console.log("组件初始化");
    }
    shouldComponentUpdate (nextProps , nextState) {
        console.log('组件是否需要更新');
        return true;
    }
    componentDidUpdate () {
        console.log('组件已经更新');
    }
    componentDidMount () {
        console.log('组件已经挂载');
        window.addEventListener('resize' , this.handleResize);
    }
    componentWillUnmount () {
        console.log('组件将被卸载');
        window.removeEventListener('resize' , this.handleResize);
    }
    handleResize = () => {
        console.log('改变窗口大小触发该事件');
    }
    render () {
        console.log('渲染');
        return (
            <button onClick={() => this.onClickHandle()}>click here</button>
        )
    }
}

class App extends Component {
    constructor (props) {
        super(props);
        this.state = {
            show : true
        }
    }
    deleteComponent = () => {
        this.setState({
            show : false
        })
    }
    render () {
        return (
            <div>
                <button onClick={this.deleteComponent}>删除组件</button>
                {
                    this.state.show ? <Button /> : null
                }
            </div>
        )
    }
}

注意点

在16.3版本以上的React中,componentWillMount,componentWillReceiveProps,componentWillUpdate将被删除,当然还是可以用的,只是被标记了不安全,今后应该会被删除。

Metadata

Metadata

Assignees

No one assigned

    Labels

    reactreact相关

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions