首先生命周期分为三个阶段:
挂载:已经插入真实dom
渲染(更新):正在被重新渲染
卸载:已经移出真实dom
一、挂载:在组件实例被创建并插入到dom中时,生命周期调用顺序如下
旧生命周期:
1.constructor(props)
2.componentWillMount()-------------可以用但是不建议使用
3.render()
4.componentDidMount()
新生命周期:
constructor(props)
static getDerivedStateFromProps(props,state)--替代了componentWillReceiveProps
render()
componentDidMount()
(1)constructor
使用场景:
一般在 constructor 中做一些组件的初始化工作,例如:初始化组件的 state。
该方法只会执行一次,调用该方法会返回一个组件实例。
在初始化阶段执行,可直接对 this.state 赋值。其他生命周期函数中只能通过 this.setState 修改 state,不能直接为 this.state 赋值。
接收props和context,当想在函数内使用这两个参数需要在super传入参数,当使用constructor时必须使用super,否则可能会有this的指向问题,如果不初始化state或者不进行方法绑定,则可以不为组件实现构造函数;
避免将 props 的值复制给 state!这是一个常见的错误:
constructor(props) {
super(props);
// 不要这样做
this.state = { color: props.color };
}
如此做毫无必要(可以直接使用 this.props.color),同时还产生了 bug(更新 prop 中的 color 时,并不会影响 state)
(2)componentWillMount
在组件挂载至 DOM 之前调用,并且只会调用一次。它在 render 方法之前调用,因此在 componentWillMount 中调用 this.setState 不会触发额外的渲染。
这个生命周期钩子使用频率较小,因为我们一般在 constructor 中初始化 state,在 componentDidMount 中引入副作用或者订阅内容。
(3)getDerivedStateFromProps
从props获取state。
它是一个静态方法,接收 propspropsprops 和 statestatestate 两个参数。它会在调用 render 方法之前被调用,不管是在初始挂载时还是在后续组件更新时都会被调用。
它的调用时机和 componentWillMount、componentWillUpdate、componentWillReceiveProps 一样都是在 render 方法被调用之前,它可以作为 componentWillMount、componentWillUpdate 和 componentWillReceiveProps 的替代方案。
当然,它的作用不止如此,它可以返回一个对象,用来更新 state,就像它的名字一样,从 props 中获取衍生的 state。如果不需要更新 state 则可以返回 null。
需要注意的是:这个生命周期函数是类的静态方法,并不是原型中的方法,所以在其内部使用 this 访问到的不是组件实例。
此生命周期钩子不常用,如果可以的话,我们也尽可能不会使用它。
static getDerivedStateFromProps(nextProps, prevState) {
const {type} = nextProps;
// 当传入的type发生变化的时候,更新state
if (type !== prevState.type) {
return {
type,
};
}
// 否则,对于state不进行任何操作
return null;
}
(4)render
render 方法是类组件中唯一必须实现的方法,它的返回值将作为页面渲染的视图。render 函数应该为纯函数,也就是对于相同的 state 和 props,它总是返回相同的渲染结果。
render 函数被调用时,会返回以下四种类型之一:
React 元素:通常为 JSX 语法。例如:
、 等等。
数组或者 fragments:render 方法可以通过数组返回多个元素。
Portals:渲染子节点至不同的子树中。
字符串或者数值:会作为文本节点被渲染。
boolean 类型或者 null:什么都不渲染。
需要注意的是:如果 shouldComponentUpdate 生命周期钩子返回 false,则 render 方法(render 阶段后续生命周期钩子)不会执行。
(5)componentDidMount
在组件挂在后(插入到dom树中)后立即调用.
该生命周期方法会在组件挂载之后执行,也只会执行一次,也就是将组件对应的 DOM 插入 DOM 树中之后调用。它会在浏览器更新视图之前调用,如果在 componentDidMount 中直接调用 this.setState,它会触发额外的渲染,会再一次调用 render 函数,但是浏览器中视图的更新只会执行一次。
可以在这里调用Ajax请求,返回的数据可以通过setState使组件重新渲染,或者添加订阅,但是要在conponentWillUnmount中取消订阅
二、更新:当组件的 props 或 state 发生变化时会触发更新。
旧生命周期:
- componentWillReceiveProps (nextProps)------------------可以用但是不建议使用shouldComponentUpdate(nextProps,nextState)
- componetnWillUpdate(nextProps,nextState)----------------可以用但是不建议使用
- render()
- componentDidUpdate(prevProps,precState,snapshot)
新生命周期:
- static getDerivedStateFromProps(nextProps, prevState)
- shouldComponentUpdate(nextProps,nextState)
- render()
- getSnapshotBeforeUpdate(prevProps,prevState)
- componentDidUpdate(prevProps,precState,snapshot)
(1)componentWillReceiveProps ()
在已挂载组件接收到新的 props 之前调用。你可以在这个函数中比较新旧 props,并根据新旧 props 更改 state。但是它会破坏 props 数据的单一数据源。
在首次渲染组件时,不会调用此生命周期钩子;使用 this.setState 触发组件更新时,也不会调用此生命周期钩子。
不过要注意:如果是父组件渲染导致了组件的重新渲染,即使传给该组件的 props 没变,该组件中的这个生命周期函数也会被调用。
我们一般不使用此生命周期函数,因为它通常会破坏数据源的单一性。
componentWillReceiveProps (nextProps) {
nextProps.openNotice !== this.props.openNotice&&this.setState({
openNotice:nextProps.openNotice
},() => {
console.log(this.state.openNotice:nextProps)
//将state更新为nextProps,在setState的第二个参数(回调)可以打 印出新的state
})
}
(2)shouldComponentUpdate
在渲染之前被调用,默认返回为true。
熟悉 React 组件生命周期的话都知道:调用 setState 方法总是会触发 render 方法从而进行 vdom re-render 相关逻辑,哪怕实际上你没有更改到 Component.state
this.state = {count: 0}
this.setState({count: 0});// 组件 state 并未被改变,但仍会触发 render 方法
为了避免这种性能上的浪费, React 提供了一个 shouldComponentUpdate 来控制触发 vdom re-render 逻辑的条件。于是 PureRenderMixin 作为一种优化技巧被使用。它仅仅是浅比较对象,深层次的数据结构根本不管用
在组件准备更新之前调用,但是首次渲染或者使用 forceUpdate 函数时不会被调用。跟它的名字一样,它用来判断一个组件是否应该更新。
默认情况下,当组件的 props 或者 state 变化时,都会导致组件更新。它在 render 方法之前执行,如果它的返回值为 false,则不会更新组件,也不会执行后面的 render 方法。
它接收两个参数,nextProps 和 nextState,即下一次更新的 props 和下一次更新的 state。我们可以将 this.props 和 nextProps 比较,以及将 this.state 与 nextState 比较,并返回 false,让组件跳过更新。不过注意:它并不会阻止子组件因为 state 改变而导致的更新。
使用场景:
这个生命周期方法通常用来做性能优化。也可以继承pureComponent来性能优化
(3)componentWillUpdate
当组件接收到新的props和state会在渲染前调用,初始渲染不会调用该方法。
shouldComponentUpdate返回true以后,组件进入重新渲染的流程,进入componentWillUpdate,不能在这使用setState,在函数返回之前不能执行任何其他更新组件的操作
此方法可以替换为 componentDidUpdate()。如果你在此方法中读取 DOM 信息(例如,为了保存滚动位置),则可以将此逻辑移至 getSnapshotBeforeUpdate() 中。
(4)getSnapshotBeforeUpdate
在最后一次渲染(提交到dom节点)之前调用,替换componetnWillUpdate
此生命周期函数在最近一次渲染提交至 DOM 树之前执行,此时 DOM 树还未改变,我们可以在这里获取 DOM 改变前的信息,例如:更新前 DOM 的滚动位置。
它接收两个参数,分别是:prevProps、prevState,上一个状态的 props 和上一个状态的 state。它的返回值将会传递给 componentDidUpdate 生命周期钩子的第三个参数。
使用场景:
需要获取更新前 DOM 的信息时。例如:需要以特殊方式处理滚动位置的聊天线程等。
(5)componentDidUpdate:在更新之后立即调用,首次渲染不会调用,之后每次重新渲染都会被调用。
可以在该方法调用setState,但是要包含在条件语句中,否则一直更新会造成死循环
当组件更新后,可以在此处对 DOM 进行操作。如果对更新前后的props进行了比较,可以进行网络请求。(当 props 未发生变化时,则不会执行网络请求)。
componentDidUpdate(prevProps) {
// 典型用法(不要忘记比较 props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为 componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。如果返回false就不会调用这个函数。
三、卸载:当组件从 DOM中移除时会调用如下方法:
(4)新旧生命周期相同:componentWillUnmount():
在组件卸载和销毁之前调用
在这执行必要的清理操作,例如,清除timer(setTimeout,setInterval),取消网络请求,或者取消在componentDidMount的订阅,移除所有监听
标签:生命周期,render,react,state,调用,详细,props,组件 From: https://www.cnblogs.com/coderz1/p/16857159.html