react入门系列之react生命周期函数

什么是生命周期函数

  1. 组件中在某个阶段会自动执行的函数。
    • 比如我们执行使用render函数,在prop或者state变化时,render函数自动执行。
    • 因此render函数就是一个生命周期函数。
  2. constructor在组件创建的时候也会自动调用。但是他不是react独有,是es6中的函数所以,我们不将他列为生命周期函数。

生命周期分为4个阶段

  1. initialization(组件初始化)
    • 我们在创建组件的时候需要继承react Component这个基类,也就继承这个react的基类,才能有render(),生命周期等方法可以使用,这也说明为什么函数组件不能使用这些方法的原因。同时也让组件能使用setState方法。
    • 然后我们在 constructor 构造函数中使用 super(props)来将父组件传递的props注入给这个组件,以及使用this.state初始化这个组件的属性。
    • 这一系列动作就是组件的初始化。
  2. mount (组件的挂载)
    • 此阶段分为三个时期
      1. componentWillMount(挂载之前)

        • 这个函数在组件挂载到DOM之前的时候执行,所以你在这里引用setState方法,是不会引起组件的重新渲染。
        • 同样这里做的事情如果放在constructor构造函数中去使用也是可以的。
        • 这个函数只会被调用一次,就是组件挂载到DOM之前的时候。其他时候是不会触发这个函数的。
      2. render(挂载中)

        • 根据组件的props和state是否变化,变化即执行,这里的变化要注意,并不是值变化。只要重新赋值,新旧值相同也会执行。
        • 然后return 一个React元素(描述组件,即UI),不负责组件实际渲染工作,之后由React自身根据此元素去渲染出页面DOM。render是纯函数(Pure function:函数的返回结果只依赖于它的参数;函数执行过程里面没有副作用。
        • 不能在里面执行this.setState,会有改变组件状态的副作用。
      3. componentDidMount(挂载完成)

        • 约定将ajax请求放在这个生命周期函数中
        • 组件挂载到DOM后被执行,只会执行一次。
  3. update (组件更新时)
    • 首先我们来了解一下什么时组件更新。只有在通过setState函数使sate和props变化或重新赋值时才叫组件更新。

    • setState引起父组件的render函数执行,同时也会引起它的子组件的render函数执行。

    • 原因是react虚拟DOM的diff算法,同级比较原理。

    • 只要重新赋值就是组件更新,如果值并没有变,也更新组件,这样就会耗性能,也是我们讲同级比较的时候说的一个弊端。

    • 接下来我们了解一下有那些周期函数

      1. componentWillReceiveProps(nextProps)

        • 此方法只调用于props引起的组件更新过程中,参数nextProps是父组件传给当前组件的新props。但父组件render方法的调用不能保证重传给当前组件的props是有变化的,所以在此方法中根据nextProps和this.props来查明重传的props是否改变,以及如果改变了要执行啥,比如根据新的props调用this.setState出发当前组件的重新render
      2. shouldComponentUpdate(nextProps, nextState)

        • 此方法通过比较nextProps,nextState及当前组件的this.props,this.state,返回true时当前组件将继续执行更新过程,返回false则当前组件更新停止,以此可用来减少组件的不必要渲染,优化组件性能。ps:这边也可以看出,就算componentWillReceiveProps()中执行了this.setState,更新了state,但在render前(如shouldComponentUpdate,componentWillUpdate),this.state依然指向更新前的state,不然nextState及当前组件的this.state的对比就一直是true了。
      3. componentWillUpdate(nextProps, nextState)

        • 此方法在调用render方法前执行,在这边可执行一些组件更新发生前的工作,一般较少用。
      4. render

        • render方法在上文讲过,这边只是重新调用。
      5. componentDidUpdate(prevProps, prevState)

        • 此方法在组件更新后被调用,可以操作组件更新的DOM,prevProps和prevState这两个参数指的是组件更新前的props和state
  • 优化弊端
  • 1.当因为父组件重新render,使得props重新被赋值,导致子组件跟着渲染.
/**
 * 方法一:解决上述弊端,可以在shouldComponentUpdate函数,组件更新前进行判断,props是否改变,再确定是否执行重新渲染。
*/
class Child extends Component {
   shouldComponentUpdate(nextProps){ 
        if(nextProps.value === this.props.value){
          return false
        }
        return true
    }
    render() {
        return <div>{this.props.value}</div>
    }
}
/**
 * 方法二:
 * 1.解决上述弊端,也可以先将this.props.value赋值给子组件的state
 * 2.再在componentWillReceiveProps函数中,使用setState去重新给stae中的属性赋值this.props.value
 * 3.文档中提到,在该函数(componentWillReceiveProps)中调用 this.setState() 将不会引起第二次渲染。
 * 4.因为componentWillReceiveProps是在props有变化的时候才会触发,所以在这里面做this.setState()一定是有改变state
*/
//
class Child extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: props.value // 先将this.props.value赋值给子组件的state
        };
    }
    componentWillReceiveProps(nextProps) { // 在props有变化的时候才会触发这个方法
        this.setState({value: nextProps.value}); // 重新赋值,引起render
    }
    render() {
        return <div>{this.state.value}</div>
    }
}
  • 2.组件本身调用setState方法,但是并没有改变state中的值。
/**
 * 也是通过shouldComponentUpdate判断新旧值是否改变,改变才做render
*/
class Test extends Component {
   constructor(props) {
        super(props);
        this.state = {
          value:1
        }
   }
   shouldComponentUpdate(nextState){ // 应该使用这个方法判断新旧值是否改变
        if(nextState.value === this.state.value){
          return false // 没有改变返回false
        }
        return true
    }

   changeState = () => { // 虽然调用了setState ,但state并无变化
        const value = this.state.value
         this.setState({
            value
         })
   }

    render() {
        return <div onClick = {this.changeState}>{this.state.value}</div>
    }
}

  1. 卸载阶段(componentWillUnmount)
  • 只有一个生命周期方法componentWillUnmount
    • 此方法在组件被卸载前调用,可以在这里执行一些清理工作,比如清楚组件中使用的定时器,清楚componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏。
  1. 在react组件中,除了render函数,其他任何生命周期函数都可以不写,因为组件继承了react中的 Component,Component内置了其他的生命周期函数
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,428评论 1 33
  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 1,005评论 0 1
  • 生命周期流程图简单如下: 组件让你把用户界面分成独立的,可重复使用的部分,并且将每个部分分开考虑。React.Co...
    Simple_Learn阅读 1,074评论 0 0
  • React 生命周期很多人都了解,但通常我们所了解的都是单个组件的生命周期,但针对Hooks 组件、多个关联组件(...
    前端js阅读 7,011评论 3 7
  • 起步 安装官方脚手架: npm install -g create-react-app 创建项目: create-...
    Twoold阅读 1,203评论 0 0