最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 深入react技术栈--React生命周期

    正文概述 掘金(千叶风行)   2021-02-15   544

    导语

    React组件的生命周期根据广义定义描述,可以分为挂载, 渲染和 卸载这几个阶段。 当渲染后的组件需要更新时, 我们会重新去渲染组件,直至卸载。
    因此,我们可以把React生命周期分成两类:

    • 当组件在挂载或卸载时
    • 当组件接收新的数据时,即组件更新时

    挂载或卸载过程

    1.组件的挂载

    组件挂载是最基本的过程,这是过程主要做的组件状态的初始化。比如

    import React, { Component } from 'react';
    
    export default class App extends Component {
        static propTypes = {
        }
    
        static defaultProps = {
        };
    
        constructor(props) {
            super(props);
            this.state = {
            };
        }
    
        // 这个在 React 16.9 就把componentWillMount 废弃了
        componentWillMount() {
            console.log('WillMount');
        }
    
        componentDidMount() {
            console.log('DidMount');
        }
    
        render() {
            return (
                <div>This is a demo.</div>
            )
        }
    }
    

    我们看到 propTypes 和 defaultProps 分别代表 props 类型检查和默认类型。 这两个属性被声明成静态属性, 意味着可以从类外面访问他们, 比如: App.propTypes 和 App.defaultProps

    两个生命周期

    • componentWillMount : render渲染方法之前执行
    • componentDidMount : 在render渲染方法之后执行

    NOTE

    1. 如果我们在 componentWillMount 中执行 setState方法, 会发生什么呢? 组件会更新 state, 但是组件只渲染一次。因此,并无意义,初始化时的 state都放在 this.state

    2. 如果我们在 componentDidMount 中执行setState方法, 又会发生什么呢?组件当然会再次更新, 不过在初始化过程就渲染了两次组件,并不好。但是有时候,比如计算组件的位置或宽度高度,就不得不让组件先渲染,更新必要的信息后,再次渲染。

    组件的卸载

    卸载只有一个:

    • componentWillUnmount : 卸载之前的生命周期

    通常,在componentWillUnmount方法中, 我们会执行一些清理方法, 如事件回收,或清除定时器等。

    数据更新过程

    更新过程一般分为2种情况:

    • 父组件向下传递 props 发生更新
    • 组件自身执行 setState 发生更新
    import React, { Component } from 'react';
    
    export default class App extends Component {
    
        constructor(props) {
            super(props);
    
            this.state = {
                count: 0,
            }
    
            this.handleClick = this.handleClick.bind(this);
        }
        
        handleClick() {
            this.setState({
                count: this.state.count + 1,
            });
        }
    
        shouldComponentUpdate(nextProps, nextState) {
            console.log(nextProps, nextState);
            return true
        }
    
        componentWillUpdate(nextProps, nextState) {
            console.log(nextProps, nextState);
        }
    
        componentDidUpdate(prevProps, prevState) {
            console.log(prevProps, prevState);
        }
    
        render() {
            return (
                <div className="header">
                    <button onClick={this.handleClick}>点击</button>
                    <div>{this.state.count}</div>
                </div>
            )
        }
    }
    

    如果组件自身的 state更新了, 那么会依次执行 shouldComponentUpdate, componentWillUpdate , render 和 componentDidUpdate

    • shouldComponentUpdate

    是一个特别的方法, 它接受需要更新的 props 和 state, 让开发者增肌必要的条件判断, 让其在需要时更新, 不需要时不更新。 因此, 当方法返回 false 的时候, 组件不再向下执行生命周期方法

    shouldComponentUpdate 的本质是用来进行正确的组件渲染怎么理解呢?
    比如: 当父节点 props 改变的时候, 在理想情况下, 只需渲染在一条链路上有关props改变的节点即可。但是,在默认情况下, React 会渲染所有的节点, 因为 shouldComponentUpdate 默认返回的 true.
    正确的组件渲染从另一个意义上说,也是性能优化的方法之一

    值得注意的是, 无状态组件是没有生命周期方法的, 这也意味着它没有 shouldComponentUpdate。 渲染到该类组件时,每次都会重新渲染。 为了更好的使用无状态组件, 我们可以选择引用 Recompose 库的 pure方法

    • componentWillUpdate

    更新过程中渲染前

    • componentDidUpdate

    更新过程渲染后

    如果组件是由父组件更新 props 而更新的, 那么在 shouldComponentUpdate 之前会执行 componentWillReceiveProps 方法。

    React新增的生命周期

    getSnapshotBeforeUpdate(prevProps, prevState)

    代替 componentWillUpdate
    常见的 componentWillUpdate的用例是在组件更新前, 读取当前某个DOM元素的状态, 并在componentDidUpdate中进行相应的处理。

    这两者的区别在于:

    1. 在react开启异步渲染模式后, componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。

    2. getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。

    此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。

    getDerivedStateFromProps(nextProps, prevState)

    代替componentWillReceiveProps()。


    起源地下载网 » 深入react技术栈--React生命周期

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元