React v16.3.1 生命周期

去年曾经使用过React,那个时候还是使用的React v14,今年又要使用到React,发现最新的React的生命周期已经有了一些变化,有一些生命阶段在v17的时候即将要被废弃,所以特此记录一下。

React有组件这一概念,对于每一个组件来说,都有其自己的生命周期,我觉得可以理解为设计模式中的模板,我们可以复写每一个方法,但是这些方法始终遵循着一个固定的顺序在运行。

生命周期的各个阶段

React生命周期有三个阶段:

1. Mounting

这个阶段表示当一个组件被实例化创建并且插入到DOM中。在这个阶段,被调用的方法有:

  • constructor()
  • static getDerivedStateFromProps()
  • componentWillMount() / UNSAFE_componentWillMount()
  • render()
  • componentDidMount()

2. Updating

当组件已经被插入到DOM中,渲染完毕后,props/state发生改变,即组件的状态发生了改变,此时组件会被重新渲染。在这个阶段,被调用的方法有:

  • componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()
  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • componentWillUpdate() / UNSAFE_componentWillUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

3. Unmounting

这个阶段意味着组件将要被移出DOM。在这个阶段,被调用的方法有:

  • componentWillUnmount()

此外还有一个特殊的阶段。

Error Handling

当在构造函数、生命周期函数或渲染的时候出现错误时,将会调用以下方法:

  • componentDidCatch()

生命周期函数详解

constructor()

此函数在组件被mount前被调用。如果实现该方法的组件是 React.Component 的子类,那么在写其他代码前需要调用 super(props) 方法,否则在构造函数中 this.props 就是 undefined,就会因此导致一些bug的产生。

该方法用于初始化 state, 和在组件实例上绑定事件 handler。需注意,初始化 state 时,只能使用this.state来进行初始化,不可以使用 setState()

如果不需要初始化任何 state,也不需要绑定任何事件的话,那么这个方法就可以不实现。(如果没有用到的话,在运行的时候浏览器上也会提示这个方法没有用哟~)

static getDerivedStateFromProps()

这个方法是相较于之前的版本新加入的方法,之前在列举各个阶段的方法时,可以发现有一些方法前边带有 UNSAFE,官方建议是使用 getDerivedStateFromProps()来代替那些方法的使用。

这个方法将会在组件实例化和接收到新的 props 的时候被调用。可以看出,当组件实例化的时候,这个方法替代了componentWillMount(),而当接收到新的 props 时,该方法替代了 componentWillReceiveProps()componentWillUpdate()

需要注意,这个方法是个 static 的方法,因此使用 this 在这个方法中并不指代本组件,如果打印出来会发现这个this在这个方法中是null。而且这个方法会返回值。 当需要更新状态时,需要返回一个 object ,如果不需要任何更新,则返回null即可。

如果由于父组件的原因导致该组件重新渲染,这个方法也会被调用, 如果只想要处理更新的话,最好加上判断条件if (nextProp !== prevProp)。另外,虽然this.setState()也会导致组件重新渲染,但并不会导致这个方法的重新调用。

componentWillMount() / UNSAFE_componentWillMount()

现在componentWillMount()UNSAFE_componentWillMount()两个方法名共存,但是在v17中,componentWillMount()将不再存在,取而代之的则是只有UNSAFE_componentWillMount()。其他类似的同样如此。官方现在是推崇使用getDerivedStateFromProps(),对于已经存在的应用,使用UNSAFE则是不推崇但是向下兼容的一种做法。

这个方法在 mounting 发生之前被调用。由于这个方法在render()前被调用,因此即使在这个方法中调用setState(),也不会导致额外的渲染。

render()

一个组件中必须有这个方法。

这个方法需要返回一下几种东西之一:

  • React elements:element 可以是一个原生的 DOM 组件 <div />, 或是一个用户自定义的组件<MyComponent />.
  • String and numbers
  • Portals: Created with ReactDOM.createPortal.
  • null
  • Booleans: 有时可能是一个类似于return test && <Child />的pattern。

当返回值为null, false, ReactDOM.findDOMNode(this)时,即返回null.

render()方法需要是一个很干净的方法,它不应改变任何组件状态,每次被调用都应该返回相同的东西,且不应与浏览器有直接的交互。如果需要跟浏览器产生交互的话,官方建议是在componentDidMount() 或其他生命周期函数中进行,而不是render()

需注意,若shouldComponentUpdate()返回值为false时,render()方法不会被调用。

componentDidMount()

这个方法在组件被mount后被立即调用。如果需要从远端加载数据的话,推荐在这个方法中初始化网络请求。

由于这个方法发生在render()之后,因此在这个方法中调用setState()会导致一次额外的渲染,只不过这次渲染会发生在浏览器更新屏幕之前。因此即使渲染了两次,用户也不会看到中间状态,即不会有那种状态突然跳一下的情况发生。对于像modalstooltips这种需要在渲染前知道尺寸大小、位置的情况来说,也是很有用。只不过,虽然在用户视觉体验上可能没有影响,但是这种操作可能会导致性能方面的问题,因此还需慎用。

componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • 16版本的react对组件的生命周期函数进行了一些修改,在每个react组件中都有以下几个生命周期方法~我们需要在...
    mytac阅读 3,117评论 0 7
  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,835评论 1 18
  • 生命周期流程图简单如下: 组件让你把用户界面分成独立的,可重复使用的部分,并且将每个部分分开考虑。React.Co...
    Simple_Learn阅读 1,079评论 0 0
  • 说在前面 关于 react 的总结过去半年就一直碎碎念着要搞起来,各(wo)种(tai)原(lan)因(le)。心...
    陈嘻嘻啊阅读 6,867评论 7 41
  • 本文解读了react生命周期的源码,如果你还是个入门的小白,当然可以忽略源码,看一看作者写的demo。也可以明白生...
    Dabao123阅读 1,307评论 0 4