【React】React组件的生命周期


组件的生命周期就是Reac的工作过程,就好比人有生老病死,自然界有日月更替,每个组件在网页中也会有被创建、更新和删除,如同有生命的机体一样。

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

  • 装载(挂载)过程 mount:组件第一次在DOM树中渲染的过程。
  • 更新过程 update:组件被重新渲染的过程。
  • 卸载过程 unmount:组件从DOM中被移除的过程。

1. 挂载过程

依次调用

  1. constructor
  2. getInitialState
  3. getDefaultProps
  4. componentWillMount
  5. render
  6. componentDidMount

1.1 constructor

就是ES6里的构造函数,创建一个组件类的实例。

在这一过程中要进行两步操作:初始化state,绑定成员函数的this环境

1.2 getInitialStategetDefaultProps

这个两个函数可以不去深究,只会在用到React.createClass方法创造的组件类才会发生作用,所以用ES6的方法定义的React组件中根本不会用到。

1.3 render

render是React组件中最为重要的一个函数。这是react中唯一不可忽略的函数,在render函数中,只能有一个父元素。

其中需要深入分析的是:render函数是一个纯函数(一个函数的返回结果只依赖其参数,并且执行过程中没有副作用。)。render并不进行实际上的渲染动作,它只是一个JSX描述的结构。
最终是由React来进行渲染过程。

render函数中不应该有任何操作,对页面的描述完全取决于this.state和this.props的返回结果,不能在render调用this.setState。

有一个公式总结的非常形象 UI=render(data)

1.4 componentWillMountcomponentDidMount

这两个函数分别在render前后执行。

componentDidMount函数作用就大得多,由于这一过程通常只能在浏览器端调用,所以我们在这里获取异步数据,而且在componentDidMount调用的时候,组件已经被装载到DOM树上了,还有,可以在这里执行其他库的代码,比如Jquery。

2. 更新过程

简单来说就是props和state被修改的过程。

依次调用:

  1. componentWillReceiveProps
  2. shouldComponentUpdate
  3. componentWillUpdate
  4. render
  5. componentDidUpdate

2.1 componentWillReceiveProps(nextProps)

并不是只有在props发生改变的时候才会被调用,实际上只要是父组件的render函数被调用,render里面被渲染的子组件就会被更新。

不管父组件传给子组件的props有没有被改变,都会触发子组件的componentWillReceiveProps过程。

但是,this.setState方法的触发过程不会调用这个函数,因为这个函数适合根据新的props的值来计算出是不是要更新内部状态的state。

2.2 shouldComponentUpdate(nextProps,nextState)

这个函数的重要性,仅次于render。

render函数决定了该渲染什么。

shouldComponentUpdate决定了不需要渲染什么,都需要返回函数,这一过程可以提高性能,忽略掉没有必要重新渲染的过程。

2.3 componentWillUpdatecomponentDidUpdate

和装载过程不同,这里的componentDidUpdate,既可以在浏览器端执行,也可以在服务器端执行。

在React中,如何触发render():

以下假设shouldComponentUpdate都是按照默认返回true的方式:

  1. 首次渲染 Initial Render
  2. 调用this.setState(),并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render。
  3. 父组件发生更新(一般为props发生改变)
  4. 调用this.forceUpdate()。

在这里插入图片描述
注意:如果在shouldComponentUpdate里面返回false可以提前退出更新路径。

3. 卸载过程

实际中很少用到。
这里只有一个 componentWillUnmount ,一般在componentDidMount里面注册的事件需要在这里删除。

4. 生命周期实例

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script src="./js/react_js/react.development.js"></script>
    <script src="./js/react_js/react-dom.development.js"></script>
    <script src="./js/react_js/babel.min.js"></script>
</head>
<body>
    <div id='container'></div>
    <script type="text/babel">
        class LifeCycle extends React.Component {
            constructor(props) {
                super(props);
                alert("Initial render");
                alert("constructor");
                this.state = {str: "hello"};
            }

            componentWillMount() {
                alert("componentWillMount");
            }
            componentDidMount() {
                alert("componentDidMount");
            }
            componentWillReceiveProps(nextProps) {
                alert("componentWillReceiveProps");
            }
            shouldComponentUpdate() {
                alert("shouldComponentUpdate");
                return true;        // 记得要返回true
            }

            componentWillUpdate() {
                alert("componentWillUpdate");
            }
            componentDidUpdate() {
                alert("componentDidUpdate");
            }
            componentWillUnmount() {
                alert("componentWillUnmount");
            }
            setTheState() {
                let s = "hello";
                if (this.state.str === s) {
                    s = "HELLO";
                }
                this.setState({
                    str: s
                });
            }
            forceItUpdate() {
                this.forceUpdate();
            }
            render() {
                alert("render");
                return(
                    <div>
                        <span>{"Props:"}<h2>{parseInt(this.props.num)}</h2></span>
                        <br />
                        <span>{"State:"}<h2>{this.state.str}</h2></span>
                    </div>
                );
            }
        }
        class Container  extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
                    num: Math.random() * 100
                };
            }
            propsChange() {
                this.setState({
                    num: Math.random() * 100
                });
            }
            setLifeCycleState() {
                this.refs.rLifeCycle.setTheState();
            }
            forceLifeCycleUpdate() {
                this.refs.rLifeCycle.forceItUpdate();
            }
            unmountLifeCycle() {
                // 这里卸载父组件也会导致卸载子组件
                ReactDOM.unmountComponentAtNode(document.getElementById("container"));
            }
            parentForceUpdate() {
                this.forceUpdate();
            }
            render() {
                return (
                    <div>
                        <a href="javascript:;"  onClick={this.propsChange.bind(this)}>propsChange</a>
                        &nbsp;&nbsp;&nbsp;
                        <a href="javascript:;"  onClick={this.setLifeCycleState.bind(this)}>setState</a>
                        &nbsp;&nbsp;&nbsp;
                        <a href="javascript:;"  onClick={this.forceLifeCycleUpdate.bind(this)}>forceUpdate</a>
                        &nbsp;&nbsp;&nbsp;
                        <a href="javascript:;"  onClick={this.unmountLifeCycle.bind(this)}>unmount</a>
                        &nbsp;&nbsp;&nbsp;
                        <a href="javascript:;"  onClick={this.parentForceUpdate.bind(this)}>parentForceUpdateWithoutChange</a>
                        <LifeCycle ref="rLifeCycle" num={this.state.num}></LifeCycle>
                    </div>
                );
            }
        }
        ReactDOM.render(
            <Container></Container>,
            document.getElementById('container')
        );
    </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南栀~zmt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值