- 在组件的每个生命周期中,随着该组件的props或者state发生改变,它的DOM表现也将有相应的改变,一个组件就是一个状态机,对于特定的输入,他总会返回一致的输出。
- React为每个组件提供了生命周期钩子函数去响应不同的时刻——实例化期、存在期及销毁时。
- 从组件被创建出来的那一刻,生命周期就开始了。
- 当浏览器关闭的时候,组件也就销毁了,或者组件切换的时候,或者用路由切换组件的时候就销毁了。
- 组件不能跨阶段去做一些事情。
- 实例化期是从初始化state以及初始props的时候一直到第一个虚拟DOM挂载到页面上。
- 存在期是挂载到页面以后与用户产生交互,一直到销毁之前都属于存在期。
- 销毁期能做的唯一一件事就是把创建的那些东西都删掉。
- 到达了相应的阶段,函数自动调用,不需要我们去调用,如果不需要做任何事情,里面就可以不用写。
生命周期方法
- 实例化期 存在期 销毁期
- 组件的生命周期,包含的主要几种情况:
- 组件被实例化的时候
- 组件属性改变的时候
- 组件状态被改变的时候
- 组件被销毁的时候
首次调用组件时,有以下方法会被调用(注意顺序,从上到下执行)。
getDefaultProps()
这个方法已经不推荐使用,它等同于constructor里面接收到的props属性。组件生命周期只会调用一次,但是只适合React.createClass直接创建的组件,使用ES6/7创建的这个方法不可使用,ES6/7可以使用下面方式。
ES6/7
class Component{
static defaultProps={}
}
当第一次调用class的时候,就先调用constructor函数,就算省略了constructor也会去调用。
实例化期
construtor(){} 首先调用该钩子函数 实例化首先发生的是状态和属性的创建。因为construtor里可以接收一个props, 如果传过来的props没有值,可以设置一个默认值
即static defaultProps={}
代码执行顺序肯定是先执行静态属性的defaultProps,再去生成初始状态,执行state,跟写的前或后没有关系
getInitialState()
设置state初始值,在这个方法中,你已经可以访问this.props。getInitialState只适合React.createClass直接创建的组件。使用ES6初始化state状态如下
class Component extends React.Component{
constructor(){
super()
this.state={
name:"tom",
}
}
}
componentWillMount(){}
- 该钩子函数会在render()钩子函数之前调用。只适合
- 条件:第一次渲染阶段在调用render方法前被调用
- 作用:该方法在整个组件生命周期只会被调用一次。所以利用该方法做一些组件内部的初始化工作,这是在render()方法调用之前可修改state的最后一次机会,我们可以最后一次修改state的初始值,并且不会调用render方法重新渲染。
- 因为放在这个钩子函数里,请求的次数也会增多,增加服务器压力。
- 该函数可能会调用多次,所以它里面基本也不放数据的请求
componentDidMount(){}
- 条件:第一次渲染成功后,组件对应的DOM已经添加到页面后调用。
- 作用:这个阶段标识组件对应的vDOM已经存在,我们可以再这个时候做一些依赖DOM的操作或者其他的一些如请求数据,和第三方库整合的操作。如果嵌套了子组件,子组件会比父组件优先渲染,所以这个时候可以优先获取子组件对应的DOM.(refs)
- 该函数调用的那一刻,就代表着虚拟DOM已经转为真实DOM,并且实例化阶段已经结束了。
- 在这个函数里可以通过原生js的方法找到真实的DOM。
- 如果第三方库需要操作真实DOM,就把第三方库写在该方法里调用,但是我们要少用这种方法操作真实DOM,如果真想操作真实DOM,先选择ref去操作。
- 而在React16之后采用了Fiber架构,该生命周期函数在整个过程中只被执行一次
以上都是实例化阶段,到这里组件第一次才加载完。
关于React中数据获取为什么一定要在componentDidMount!里面调用?
- ·constructor()中获取数据的话,如果时间太长,或者出错,组件就渲染不出来,整个页面都没法渲染
- ·constructor是做组件state初始化工作,并不是设计来作加载数据的。
- 了。
- ·如果使用SSR(服务端渲染),componentWillMount会执行2次,一次在服务端,一次在客户端。而
- componentDidMount不会,
- ·React16之后采用了Fiber架构,只有componentDidMount生命周期函数是确定被执行一次的,类似 ComponentWillMount的生命周期钩子函数都有可能执行多次,所以不建议在这些生命周期中做有副作用的操作,比如请求数据之类。
- componentDidMount方法中的代码,是在组件己经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重新渲染。所以,官方设计这个方法就是用加载外部数据用的,或处理其他的副作用代码。