废弃了一些 API( componentWillMount, componentWillReceiveProps, and componentWillUpdate),同时推出了一些新的 API 代替,包括 getDerivedStateFromProps 根据应用场景的不同, getDerivedStateFromProps的使用方式也不同。 一、半受控组件 虽然 React 官方不推荐半受控组件,当然从 API 设计和维护的角度考虑也是不推荐的。 而使用 getDerivedStateFromProps就会直观一些: class SomeSearchableComponent extends Component { state = { ; } else { this.setState({ search: e.target.value, }); } }; static getDerivedStateFromProps 大部分情况下,不推荐使用 getDerivedStateFromProps。
挂载阶段源码分析 挂载(mount)阶段,依次执行的方法顺序为: (1)constructor; (2)static getDerivedStateFromProps; (3)componentWillMount getDerivedStateFromProps getDerivedStateFromProps 是类静态方法,可以拿到最新的 props,然后将返回的对象合并到 state 上。 , ) { const prevState = workInProgress.memoizedState; let partialState = getDerivedStateFromProps 该函数只会在 getDerivedStateFromProps 和 getSnapshotBeforeUpdate 不存在时才会触发。 这个逻辑还是在 mountClassInstance 下。 // ... // 这里还有执行 componentWillMount if ( typeof ctor.getDerivedStateFromProps !
getDerivedStateFromProps 在初始化和更新中都会被调用,并且在 render 方法之前调用,它返回一个对象用来更新 state getDerivedStateFromProps 是类上直接绑定的静态 ="109"/>,document.querySelector('.test')) count 的值不会改变,一直是 109 2. componentWillMount 执行(即将废弃) 如果存在 getDerivedStateFromProps 或者 componentWillMount -> render -> componentDidMount 更新阶段 这里记录新生命周期的流程 1. getDerivedStateFromProps 执行 执行生命周期getDerivedStateFromProps, 返回的值用于合并 state,生成新的state。 总结 初始化 constructor() static getDerivedStateFromProps() render() componentDidMount() 更新 static getDerivedStateFromProps
-> render -> componentDidMount 组件更新时会经历: getDerivedStateFromProps -> shouldComponentUpdate -> render static getDerivedStateFromProps(props, state) getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用 如果你需要,可以通过提取组件 props 的纯函数及 class 之外的状态,在getDerivedStateFromProps()和其他 class 方法之间重用代码。 但是为什么要用「getDerivedStateFromProps」代替 「componentWillReceiveProps」 呢,除了简化派生 state 的代码,是否还有别的原因? 「getDerivedStateFromProps」 相较于 「componentWillReceiveProps」 来说不是做加法,而是做减法,是 React 在推行「只用 getDerivedStateFromProps
(nextProps, prevState),getSnapshotBeforeUpdate(prevProps, prevState) 挂载阶段:getDerivedStateFromProps - - componentDidUpdate 卸载阶段:componentWillUnmount static getDerivedStateFromProps(nextProps, prevState) 子组件修改自身state 子组件 getDerivedStateFromProps 子组件 shouldComponentUpdate 子组件 render 子组件 getSnapShotBeforeUpdate 子组件 componentDidUpdate 父组件修改props 父组件 getDerivedStateFromProps 父组件 shouldComponentUpdate 父组件 render 子组件 componentDidUpdate 父组件 componentDidUpdate 卸载子组件 父组件 getDerivedStateFromProps 父组件 shouldComponentUpdate
React 团队为了确保 getDerivedStateFromProps 这个生命周期的纯洁性,直接从命名层面约束了它的用途(getDerivedStateFromProps 直译过来就是“从 Props 认识 getDerivedStateFromProps 这个新生命周期方法的调用规则如下: static getDerivedStateFromProps(props, state) 在使用层面,你需要把握三个重点 第三个重点,getDerivedStateFromProps 需要一个对象格式的返回值。 关于 getDerivedStateFromProps 是如何代替componentWillReceiveProps 的,在“挂载”环节已经讨论过:getDerivedStateFromProps 可以代替 因此,getDerivedStateFromProps 生命周期替代 componentWillReceiveProps 的背后,是 React 16 在强制推行“只用 getDerivedStateFromProps
----让组件在 props 变化时更新 state 官方文档 static getDerivedStateFromProps(props, state) getDerivedStateFromProps 如果返回的不是一个js对象,那么效果等同于null 此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props getDerivedStateFromProps 的存在只有一个目的:让组件在 class B extends React.Component { state={count:520} static getDerivedStateFromProps(props,state) 初始化阶段: 由ReactDOM.render()触发—初次渲染 1.constructor() 2.getDerivedStateFromProps 3.render() 4.componentDidMount 更新阶段: 由组件内部this.setSate()或父组件重新render触发 1.getDerivedStateFromProps 2.shouldComponentUpdate() 3.render
hooks的周期会在hooks章节讲解,这一章的使命周期主要针对类组件,各阶段生命周期执行情况看下图: react源码11.1 render阶段: mount时:组件首先会经历constructor、getDerivedStateFromProps 、componnetWillMount、render update时:组件首先会经历componentWillReceiveProps、getDerivedStateFromProps、shouldComponentUpdate react源码11.3 mount时:首先会按照深度优先的方式,依次构建wip Fiber节点然后切换成current Fiber,在render阶段会依次执行各个节点的constructor、getDerivedStateFromProps componnetDidMount update时:同样会深度优先构建wip Fiber树,在构建的过程中会diff子节点,在render阶段,如果返现有节点的变化,例如上图的c2,那就标记这个节点Update Flag,然后执行getDerivedStateFromProps
各阶段生命周期执行情况 函数组件hooks的周期会在hooks章节讲解,这一章的使命周期主要针对类组件,各阶段生命周期执行情况看下图: 图片 render阶段: mount时:组件首先会经历constructor、getDerivedStateFromProps 、componnetWillMount、render update时:组件首先会经历componentWillReceiveProps、getDerivedStateFromProps、shouldComponentUpdate 时更新的具体顺序: 图片 图片 mount时:首先会按照深度优先的方式,依次构建wip Fiber节点然后切换成current Fiber,在render阶段会依次执行各个节点的constructor、getDerivedStateFromProps componnetDidMount update时:同样会深度优先构建wip Fiber树,在构建的过程中会diff子节点,在render阶段,如果返现有节点的变化,例如上图的c2,那就标记这个节点Update Flag,然后执行getDerivedStateFromProps
我们将引入两个新的生命周期,静态的 getDerivedStateFromProps 和 getSnapshotBeforeUpdate。 新的生命周期:getDerivedStateFromProps {#new-lifecycle-getderivedstatefromprops} class Example extends React.Component { static getDerivedStateFromProps(props, state) { // ... } } 新的静态 getDerivedStateFromProps 生命周期方法在组件实例化之后以及重新渲染之前调用 你可能想知道为什么我们不将上一个 props 作为参数传递给 getDerivedStateFromProps。 如果你实现了上述建议,那么依赖于新的静态 getDerivedStateFromProps 生命周期的组件会发生什么情况呢?
render 阶段render 阶段会执行众多生命周期钩子,例如:在首次渲染时执行 constructor、getDerivedStateFromProps、componentWillMount、render getDerivedStateFromProps它是一个静态方法,接收 props 和 state 两个参数。 并引入了一个新的生命周期钩子:getDerivedStateFromProps。 但是需要注意:getDerivedStateFromProps 是一个静态方法,不能通过 this 获取到组件实例,如果我们要拿到组件的 props 和 state,必须要通过参数才能拿到。 后,不管是不是通过调用 this.setState 导致的组件更新,都会执行 getDerivedStateFromProps 生命周期函数。
P.S.更多相关讨论见Documentation for componentWillReceiveProps() is confusing 二.如何理解getDerivedStateFromProps getDerivedStateFromProps是用来替代componentWillReceiveProps的,应对state需要关联props变化的场景: getDerivedStateFromProps 也就是说,只要走进更新流程(无论更新原因是props change还是state change),就会触发getDerivedStateFromProps 就具体实现而言,与计算nextContext( 成了计算nextState的必要环节: getDerivedStateFromProps is invoked right before calling the render method, both value.state : null; const getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof
getDerivedStateFromProps 在初始化和更新中都会被调用,并且在 render 方法之前调用,它返回一个对象用来更新 state getDerivedStateFromProps 是类上直接绑定的静态 ="109"/>,document.querySelector('.test')) count 的值不会改变,一直是 109 2. componentWillMount 执行(即将废弃) 如果存在 getDerivedStateFromProps 或者 componentWillMount -> render -> componentDidMount 更新阶段 这里记录新生命周期的流程 1. getDerivedStateFromProps 执行 执行生命周期getDerivedStateFromProps, 返回的值用于合并 state,生成新的state。 总结 初始化 constructor() static getDerivedStateFromProps() render() componentDidMount() 更新 static getDerivedStateFromProps
初始化阶段: 由ReactDOM.render()触发---初次渲染 constructor() getDerivedStateFromProps render() componentDidMount 更新阶段: 由组件内部this.setSate()或父组件重新render触发 getDerivedStateFromProps shouldComponentUpdate() render() getSnapshotBeforeUpdate 初始化阶段: 由ReactDOM.render()触发---初次渲染 1. constructor() 2. getDerivedStateFromProps 更新阶段: 由组件内部this.setSate()或父组件重新render触发 1. getDerivedStateFromProps 2. shouldComponentUpdate static getDerivedStateFromProps(props,state){ console.log('getDerivedStateFromProps',props,state
打开之前 React 的生命周期文档网页,点击展开不常用的生命周期如下:图片getDerivedStateFromProps 函数:组件在被挂载或者更新时 (映射数据),就会回调shouldComponentUpdate constructor(props) { super(props); this.state = { count: 0 } } static getDerivedStateFromProps (props, state) { console.log('挂载或更新时-映射数据-getDerivedStateFromProps'); console.log(props div> <Home name={'yangbuyiya'}/>
触发顺序为: componentWillReceiveProps(废弃,所以上图中没有,但还是要说说) static getDerivedStateFromProps shouldComponentUpdate 调用 getDerivedStateFromProps const getDerivedStateFromProps = ctor.getDerivedStateFromProps; applyDerivedStateFromProps , ) { const prevState = workInProgress.memoizedState; let partialState = getDerivedStateFromProps 调用 getDerivedStateFromProps // 是否应该更新组件 // 3. 调用 getDerivedStateFromProps // 是否应该更新组件 // 3.
= ctor.getDerivedStateFromProps; //从开发角度上看,只要有调用getDerivedStateFromProps()或getSnapshotBeforeUpdate () //其中一个生命周期API,变量 hasNewLifecycles 就为 true const hasNewLifecycles = typeof getDerivedStateFromProps ()」是互斥关系 //这边能执行,说明componentWillReceiveProps()就不执行 if (typeof getDerivedStateFromProps === 'function ') { applyDerivedStateFromProps( workInProgress, ctor, getDerivedStateFromProps = ctor.getDerivedStateFromProps; const hasNewLifecycles = typeof getDerivedStateFromProps ===
初始化阶段: 由ReactDOM.render()触发---初次渲染 constructor() getDerivedStateFromProps render() componentDidMount 更新阶段: 由组件内部this.setSate()或父组件重新render触发 getDerivedStateFromProps // 若state的值在任何时候都取决于props,那么可以使用getDerivedStateFromProps this.forceUpdate() 28 } 29 30 //若state的值在任何时候都取决于props,那么可以使用getDerivedStateFromProps 31 static getDerivedStateFromProps(props,state){ 32 console.log('getDerivedStateFromProps
各阶段生命周期执行情况 函数组件hooks的周期会在hooks章节讲解,这一章的使命周期主要针对类组件,各阶段生命周期执行情况看下图: render阶段: mount时:组件首先会经历constructor、getDerivedStateFromProps 、componnetWillMount、render update时:组件首先会经历componentWillReceiveProps、getDerivedStateFromProps、shouldComponentUpdate update时更新的具体顺序: mount时:首先会按照深度优先的方式,依次构建wip Fiber节点然后切换成current Fiber,在render阶段会依次执行各个节点的constructor、getDerivedStateFromProps componnetDidMount update时:同样会深度优先构建wip Fiber树,在构建的过程中会diff子节点,在render阶段,如果返现有节点的变化,例如上图的c2,那就标记这个节点Update Flag,然后执行getDerivedStateFromProps
为什么要先讲render在mount和update阶段的整体流程呢,这是因为react生命周期就是穿插在这些子阶段中执行的,来看一张图 render阶段: mount时:组件首先会经历constructor、getDerivedStateFromProps 、componnetWillMount、render update时:组件首先会经历componentWillReceiveProps、getDerivedStateFromProps、shouldComponentUpdate react源码11.3 mount时:首先会按照深度优先的方式,依次构建wip Fiber节点然后切换成current Fiber,在render阶段会依次执行各个节点的constructor、getDerivedStateFromProps componnetDidMount update时:同样会深度优先构建wip Fiber树,在构建的过程中会diff子节点,在render阶段,如果返现有节点的变化,例如上图的c2,那就标记这个节点Update Flag,然后执行getDerivedStateFromProps