所有生命周期方法:
constructor
【new】getDerivedStateFromProps
render
componentDidMount
【new】getDerivedStateFromProps
shouldComponentUpdate
render
【new】getSnapshotBeforeUpdate
componentDidUpdate
componentWillUnmount
【new】getDerivedStateFromError
【new】componentDidCatch
constructor (props)
constructor 一般用来初始化 state,声明 ref,绑定方法。
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
};
this.ref = React.createRef();
this.handleClick = this.handleClick.bind(this)
}
}
【new】static getDerivedStateFromProps (props, state)
getDerivedStateFromProps 会在两个时间触发:一是首次 render 之前,另一次是每次组件更新时 shouldComponentUpdate 之前。这里先讲首次 render 之前触发,这个时候使用一般是用来根据 props 的值初始化 state,当然可以直接在 constructor 里初始化 state。
static getDerivedStateFromProps(props, state) {
return {count: props.count};
}
render
render 主要作用就是返回一段 jsx,表示想要渲染的内容。如果返回值是 null 或 false 则不会渲染任何内容。
render () {
return (
<div>
<h1>title</h1>
<p>description</p>
</div>
)
}
componentDidMount
一般在 componentDidMount 里处理组件装载好之后才可以进行的操作,比如绑定事件、发送数据请求、或者进行一些 dom 相关的操作。
componentDidMount () => {
window.addEventListener(‘scroll’, this.handleScroll)
this.timeout = setTimeout(() => {
console.log(new Date())
}, 500)
}
【new】static getDerivedStateFromProps (props, state)
当 props 改变或 state 改变时,组件重新渲染就会再次进入该声明周期方法中。这个时候可以根据 props 的值来更新 state,返回新的 state 值,返回 null 则表示不更新。在旧的生命周期方法 componentWillReceiveProps 中,我们经常会比较 this.props 和 nextProps 来决定是否更新 state 或做别的事情,比如:
componentWillReceiveProps (nextProps) {
if (this.props.count !== nextProps.count) {
this.setState({count: nextProps.count})
this.fetchData()
}
}
getDerivedStateFromProps 是静态方法,无法取到当前类组件的实例,所以没有办法进行 this.prop 和 nextProps 的比较,如果要比较的话只能进行 props 和当前 state 的比较,如下:
if (props.count !== state.count) {
return {
…
count: props.count,
};
// 不更新 state
return null
}
除了不能比较 this.prop 和 nextProps 外,也不能在这个方法里调用当前实例的其他方法,比如 this.fetchData,想调用的话得在 componentDidUpdate 里调用,这里在 componentDidUpdate 里会讲到。
shouldComponentUpdate (nextProps, nextState)
当 props 或 state 的改变而使得组件需要重新渲染时,就会进入这个生命周期方法,它在 render 前触发。这个方法返回一个布尔值,用来表示组件是否需要重新渲染,默认值是 true,表示总是重新渲染。我们可以在这里加一些判断逻辑,只有当一些我们真正关心的数据改变时我们才重新渲染,比如:
shouldComponentUpdate(nextProps, nextState) {
// 只有 count 改变页面才更新
return nextState.count !== this.state.count;
}
【new】getSnapshotBeforeUpdate (prevProps, prevState)
这个方法会在组件更新时,render 方法之后,但是 dom 还没有发生更新前执行。这我们可以根据更新前的 props 和 state 返回一个值,这个值将会作为下一个生命周期方法 componentDidUpdate 的第三个参数传入。可以用来与 componentDidUpdate 协作完成一些事情。
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevState.blocks.length < this.state.blocks.length) {
const grid = this.grid.current;
const isAtBottomOfGrid =
window.innerHeight + window.pageYOffset === grid.scrollHeight;
return {isAtBottomOfGrid};
}
return null;
}
componentDidUpdate (prevProps, prevState, snapshot)
该生命周期方法会在更新完成后执行,一般在这里做的事情是:根据 props 的改变做一些操作比如请求数据,根据 snapshot 的值做一些操作,或者是做一些 dom 操作等等。
1、根据 props、state 的改变做一些处理在旧的生命周期方法 componentWillReceiveProps 中,经常会比较 this.props 和 nextProps,来进行其他操作比如请求数据,或调用 this.someFunc 等,在新的生命周期方法中这部分操作可以在 componentDidUpdate 中完成。
componentDidUpdate (prevProps, prevState, snapshot) {
if (this.props.count !== prevProps.count) {
this.fetchData()
}
}
2、根据第三个参数 snapshot 做一些处理比如以下例子就是根据上面 getSnapshotBeforeUpdate 里返回的 isAtBottomOfGrid 来判断当前页面的滚动条是不是在底部,如果是的话,更新后还需要手动将滚动条滚到底部。
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot.isAtBottomOfGrid) {
window.scrollTo({
top: this.grid.current.scrollHeight,
behavior: ‘smooth’,
});
}
}
componentWillUnmount
这个方法与 componentDidMount 是相对应的,在 componentDidMount 中绑定的事件、创建的定时器都可以在这个方法里清除。
componentWillUnmount () => {
window.removeEventListener(‘scroll’, this.handleScroll}
clearTimeout(this.timeout)
}
【new】static getDerivedStateFromError(error)
这个方法用来获取子组件抛出的错误,根据错误信息返回一个对象,为新的 state 的值。只能获取到子组件生命周期方法中抛出的错误,像 this.handleClick 里抛出的错误,不会触发该方法。这个方法只能用来返回错误,如果想打印错误或做其他处理,需要在 componentDidCatch 里写。
static getDerivedStateFromError(error) {
return {hasError: true};
}
【new】componentDidCatch(error, info)
当子组件中抛出错误后,componentDidCatch 就会触发,可以在这个方法里捕获错误、打印错误信息或上报错误信息等操作。
componentDidCatch(error, info) {
console.log(error, info);
}
参考:React 16 Lifecycle Methods: How and When to Use Them