React生命周期
react生命周期可以从广义分为三个阶段,即挂载、渲染、卸载。在这个过程中提供有很多生命周期钩子函数,在不同生命周期可以被调用。

挂载过程
当组件实力被创建并且被插入DOM中时,生命周期如下:
-
constructor()构造函数 一般不可以调用setState方法,只绑定初始状态-
组件挂载之前会调用构造函数
-
为子类实现构造函数时候,在构造函数内调用
super(props)constructor(props) { super(props); } -
通过在构造函数内使用
this.state对象初始化内部的state -
在给state赋值初始值时候避免将
props赋值给state,这是一个常见的错误
-
-
static getDerivedStateFromProps(props,state)从props中获取衍生的状态- 调用
render方法之前调用 - 并且在初始化、更新阶段都会被调用
- 返回一个对象更新
state,如果返回null则不更新
- 调用
-
componentWillMount()组件即将挂载 在新的生命周期中已经废除(谨慎使用) -
render()渲染函数 -
componentDidMount()组件挂载完成后,立即调用
下述方法即将过时谨慎使用:
UNSAFE_componentWillMount()
更新过程
当组件的props或者state发生变化时,组件生命周期如下:
-
compontentWillReceiveProps(nextProps)组件即将接收props阶段 -
static getDerivedStateFromProps(props,state)获取新的状态 -
shouldCompontentUpdate(nextProps,nextState)判断是否应该更新- 会在组件渲染之前被调用,返回值默认为true
- 首次渲染使用
forceUpdate()时不会调用该方法 - 返回值
true更新false不更新 - 默认
state每次发生变化组件都会重新渲染 - 如果考虑性能优化可以使用内置的
PureComponent组件,PureComponent会对props和state进行浅层次的比较,并且减少不必要的更新 - 如果
shouldComponentUpdate()返回false,将不会调用compoentWillUpdate(),render()和componentDidUpdate(),并且返回false仍然可能导致组件重新渲染
-
componentWillUpdate(nextProps,nextState)- 当组件接收到新的
props和state时,会在渲染之前调用 - 初始渲染不会调用
- 不能在此方法中调用
this.setState,也不能进行其他操作出发组件更新
- 当组件接收到新的
-
render() -
getSnapshotBeforeUpdate(prevProps,prevState)获取快照- 他的返回值将作为
componentDidUpdate()的第三个参数 - 否则此参数为
undefined
- 他的返回值将作为
-
compontentDidUpdate(pervProps,prevState,snapshot)-
会在更新结束之后立即被调用
-
首次渲染不会执行
-
当组件更新后可以对DOM进行操作
-
可以在该钩子函数中调用
setState,但必须包裹在一个条件语句中不然会导致死循环componentDidUpdate(prevProps) { // 典型用法(不要忘记比较 props): if (this.props.userID !== prevProps.userID) { this.fetchData(this.props.userID); } }
-
下述方法即将过时,在新代码中应该避免使用:
UNSAFE_componentWillUpdate(nextProps,nextState)UNSAFE_compontentWillReceiveProps(nextProps)
卸载过程
当组件从DOM中移除时,会调用以下钩子函数:
componentWillUnmount()- 会在组件卸载之前调用
- 可以用作清理操作,例如清除timer、解绑事件,取消网络请求或者清除在
componentDidMount()中创建的订阅 - 不能在此钩子函数中调用
setState,因为组件永远不会被重新渲染
错误处理
当渲染,生命周期或者构造函数中抛出错误时,会调用以下钩子函数:
-
static getDerivedStateFromError(error)-
后代组件抛出错误时候调用
-
返回一个值更新state
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可以显降级 UI return { hasError: true }; } render() { if (this.state.hasError) { // 你可以渲染任何自定义的降级 UI return <h1>Something went wrong.</h1>; } return this.props.children; } }
-
-
componentDidCatch(error, info)-
后代组件抛出错误时候调用
-
error 抛出的错误
-
info 带有componentStack key的对象,包含引发错误的错误栈信息
-
允许支持副作用
lass ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可以显示降级 UI return { hasError: true }; } componentDidCatch(error, info) { // "组件堆栈" 例子: // 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) { // 你可以渲染任何自定义的降级 UI return <h1>Something went wrong.</h1>; } return this.props.children; } }
-
本文详细介绍了React组件的生命周期,包括挂载、渲染和卸载阶段的关键钩子函数,如constructor、getDerivedStateFromProps、shouldComponentUpdate等,并讨论了错误处理和性能优化。同时,强调了部分生命周期方法的废弃和替代方案,如UNSAFE_前缀的方法。文章还提到了如何在生命周期方法中进行适当的DOM操作和状态更新,以及如何利用PureComponent进行性能提升。
9539

被折叠的 条评论
为什么被折叠?



