首先看一下新旧生命周期的对比
- 目的:为 async rendering 和 fiber 调度服务的,确保渲染完成之前不做任何引发重新渲染的操作
- async rendering:react将来会采用异步渲染机制
1 | function setState(state, callback) { |
- fiber => 节点,涉及到react渲染原理和diff算法
getDerivedStateFromProps的几个点
- react16.3版本引入
- 替换componentWillMount componentWillReceiveProps周期,从上面新旧周期函数对比就能看出
- 参数:nextProps prevState,不引入prevProps是为了节省性能
- 目的:使组件能够根据props的变化更新其内部状态,变得更为安全
- 返回值问题:
- 返回object对象,则相当于进行了一次setState操作,这里返回对象虽然改变了state,但不会再次出发该函数;
- 返回null,则不更新state
- 不返回值,则默认返回undefined,会报错
- 返回基本类型值,则与返回null是一样的结果
- 不能与17.x版本即将删除的三个生命周期函数调用
与componentWillReceiveProps的比较
- 不会产生副作用,以往我会在componentWillReceiveProps里更新state,并执行ajax异步操作,官方认为这样不够优雅,职能不专一,且渲染过程会被打断,所以新版中,将副作用放在componentDidMount和componentDidUpdate中执行
- 执行时机的不同:getDerivedStateFromProps会在组件实例化和接收到新的props的时候都会被调用
- static 静态方法,拿不到this及实例的属性和方法
- 贴个项目里用的demo
1 | state={loading: false}; |
getDerivedStateFromProps使用中存在的问题
- props和state的变化都会触发getDerivedStateFromProps函数的执行,会引发多次渲染
- 子组件接收父组件的属性,但又要通过自身setState去更新这个属性时,会造成无法更新子组件的属性
- 不要无条件的去更新state,这点尤为重要
在hooks中实现getDerivedStateFromProps函数
1 | function ScrollView({row}) { |
我们一定使用getDerivedStateFromProps这个周期函数
- 答案:不是的,甚至react官方将其称之为反模式,违反设计语言,不推荐使用
- react官方推荐,完全受控组件,及子组件的状态完全受控于父组件,即使你子组件试图更改传过来的状态,也通过替他方式
- 下面贴图
1 | // PureComponents只会在至少state和props中有一个属性发生变化时渲染. |
1 |
|