生命周期函数是指在某一特定时刻组件会自动调用执行的函数。
react生命周期可分为3个阶段:挂载
,更新
及销毁
。
在挂载前会先进行初始化过程,这个阶段组件会初始化自己的数据,如state、props。
//初始化位置
constructor(props) {
super(props);
this.state = {value: ''};
//事件处理函数的绑定该实例上
this.handleChange = this.handleChange.bind(this);
}
Mounting
组件被挂载前后,函数的执行顺序:
-
constructor()
-
static getDerivedStateFromProps()
getDerivedStateFromProps
在render()之前调用,包括初次挂载和后续更新。它的返回值若为一个对象,则更新状态,若返回null,则不更新任何内容。
//这个函数接收两个参数,新的属性作为第一个参数,先前的状态作为第二个参数
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.currentId !== nextProps.itemId) {
return {
currentId: nextProps.itemId
};
}
return null;
}
render()
创建虚拟dom,进行diff算法,渲染更新dom树都在此进行。此时不能更改state了。componentDidMount()
在render()函数后立即调用,在这个函数中适合:- ajax
- 事件订阅
Updating
组件被更新时,函数的执行顺序:
-
static getDerivedStateFromProps()
-
shouldComponentUpdate()
在props或state改变时,在render()之前调用shouldComponentUpdate()。初始渲染或使用forceUpdate()时不会调用此方法。
函数接收新的属性作为第一个参数,新的状态作为第二个参数。当函数返回 true 的时候,周期函数会继续往下执行 render 渲染;当函数返回 false,周期函数则会中止于此,并停止下面的渲染。如果不设置,这个函数会默认返回 true。
利用这个方法,我们可以避免无用的渲染,提升页面的性能。 -
render()
-
getSnapshotBeforeUpdate()
该周期函数的时期处在 render 函数执行之后和组件 DOM 渲染之前。该函数的返回值将作为 componentDidUpdate 周期函数的第三个参数。
eg:scroll position
getSnapshotBeforeUpdate(prevProps, prevState) {
// Are we adding new items to the list?
// Capture the scroll position so we can adjust scroll later.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate()
更新后立即调用componentDidUpdate()。
初始渲染不会调用此方法。这里也比较适合发送ajax请求。
如果shouldComponentUpdate()返回false,则不会调用componentDidUpdate()。
//componentDidUpdate(prevProps, prevState, snapshot)
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
Unmounting
组件被销毁时,函数的执行顺序:
componentWillUnmount()
componentWillUnmount 函数在组件被卸载和销毁之前被调用。在该方法里做清理工作,例如解绑定时器,取消网络请求,清理任何在 componentDidMount 环节创建的 DOM 元素,取消事件订阅。
异常处理
componentDidCatch()
在后代组件抛出错误后调用此生命周期。componentDidCatch()在“commit” phase被调用,
//componentDidCatch(error, info)
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, info) {
// Example "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logComponentStackToMyService(info.componentStack);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
React v17将废弃的API:
componentWillMount
componentWillReceiveProps
componentWillUpdate