高阶组件和生命周期
生命周期
旧生命周期
组件挂载
- constructor
state 初始化、事件处理函数 this 绑定..
componentWillMount
render
React 更新 DOM 和 ref
componentDidMount
组件更新(state 或者 props 发生变化)
props
- componentWillRecieveProps(nextProps): void
这个生命周期主要为我们提供对 props 发生改变的监听,如果你需要在 props 发生改变后,相应改变组件的一些 state。在这个方法中改变 state 不会二次渲染,而是直接合并 state。
state & props
- shouldComponentUpdate(nextProps,nextState)
true - 继续向下执行
false - 不更新
componentWillUpdate(nextProps,nextState)
render
React 更新 DOM 和 ref
ComponentDidUpdate(prevProps,prevState)
forceUpdate()
render
React 更新 DOM 和 ref
ComponentDidUpdate(prevProps,prevState)
在此时已经完成渲染,Dom 已经发生变化,State 已经发生更新,prevProps、prevState 均为上一个状态的值。
在 render 之前 state 和 props 都没有真正发生改变
组件卸载
- componentWillUnmount
组件执行一些清除工作
因为 React Fiber 的出现,导致组件的更新可能会被中断然后重新开始,所以 render 之前的生命周期都可能会被多次执行,React 废弃了 componentWillMount、ComponentWillReceiveProps、ComponentWillUpdate,引入了新的生命周期钩子 static getDerivedStateFromProps 和 getSnapshotBeforeUpdate
新的生命周期
组件挂载
- constructor
state 初始化、事件处理函数 this 绑定..
- static getDerivedStateFromProps(nextProps, prevState)
该方法返回一个对象,会和 state 进行合并,如果返回 null 则不更新任何内容,且不会触发 re-render 这个生命周期为我们提供了一个可以在组件实例化,props/state 更新的时候根据 props 来更新 state 的方式,用来替代旧的生命周期中的 componentWillMount 和 componentWillReceiveProps。它是一个静态的方法
render
React 更新 DOM 和 ref
componentDidMount
组件更新(state 或者 props 发生变化)
state & props
static getDerivedStateFromProps(nextProps, prevState)
shouldComponentUpdate(nextProps,nextState)
true - 继续向下执行
false - 不更新
render
getSnapshotBeforeUpdate(prevProps, prevState) - this.state 和 this.props 都已经被更新
在 render 调用之后,实际 DOM 渲染之前,在这个阶段我们可以拿到上一个状态 DOM 元素元素的坐标和大小等相关信息。可以用来代替 componentWillUpdate 生命周期,该生命周期的返回值可以作为 componentDidUpdate 的第三个参数出现
在最近一次的渲染输出被提交之前调用。也就是说,在 render 之后,即将对组件进行挂载时调用。
React 更新 DOM 和 ref
ComponentDidUpdate(prevProps,prevState)
forceUpdate()
render
getSnapshotBeforeUpdate(prevProps, prevState) - this.state 和 this.props 都已经被更新
React 更新 DOM 和 ref
ComponentDidUpdate(prevProps,prevState)
在此时已经完成渲染,Dom 已经发生变化,State 已经发生更新,prevProps、prevState 均为上一个状态的值。
在 render 之前 state 和 props 都没有真正发生改变;换句话说就是 render 之后 this.state&this.props 都已经被更新为新的值
组件卸载
- componentWillUnmount
高阶组件(HOC)
高阶组件本身不是组件,它是一个参数为组件,返回值也是一个组件的函数。作用:强化组件,复用逻辑
经典的高阶组件
- react-router 中的 withRouter
用过 withRouter withRouter 用途就是,对于没有被 Route 包裹的组件,给添加 history 对象等和路由相关的状态,方便我们在任意组件中,都能够获取路由状态,进行路由跳转,这个 HOC 目的很清楚,就是强化 props,把 Router 相关的状态都混入到 props 中
- react-redux 中的 connect
注意事项
- 谨慎修改原型链
- 继承静态属性
- 跨层级捕获 ref
高阶组件的约定是将所有 props 传递给被包装组件,但这对于 refs 并不适用。那是因为 ref 实际上并不是一个 prop - 就像 key 一样,它是由 React 专门处理的。如果将 ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。我们可以通过 forwardRef 来解决这个问题。
- render 不能生命 HOC
因为每一次 HOC 都会返回一个新的 WrapHome,react diff 会判定两次不是同一个组件,那么每次 Index 组件 render 触发,WrapHome,会重新挂载,状态会全都丢失。