一、本文布景

在项目过程中遇到了同一文件路径不同参数,路由跳转后并未调用componentWillDidMount,因而用到了React新生命周期:static getDerivedStateFromProps(nextProps, preState)并在此记录,信任下文会有您遇到的问题的解决方案!

二、文章头绪

由于文章略显繁琐,文字繁杂,附上文章头绪:

React新生命周期getDerivedStateFromProps的理解与使用

三、具体内容

1.getDerivedStateFromProps的呈现:

componentWillReceiveProps在React新的生命周期中被取消,这个生命周期函数是为了代替componentWillReceiveProps,所以在需求运用componentWillReceiveProps的时分,就能够考虑运用getDerivedStateFromProps来进行代替了。

2.getDerivedStateFromProps的功用:

我的了解:getDerivedStateFromProps这个办法名现已非常语义话了,简单翻译过来便是从Props中获得State,所以该函数的功用便是从更新后的props中获取State,它让组件在 props 产生改动时更新它自身的内部 state

3.getDerivedStateFromProps的参数:

nextProps:与componentWillReceiveProps的nextProps参数相同。即改动后的Props

preState:产生改动前的state中各数据的值。

4.getDerivedStateFromProps的触发条件:

会在调用 render 办法之前调用,即在烘托 DOM 元素之前会调用,并且在初始挂载及后续更新时都会被调用。 结合下图新React生命周期了解起来会简单一些:

React新生命周期getDerivedStateFromProps的理解与使用

5.getDerivedStateFromProps的运用:

①当props数据某个值产生改动时对state进行赋值:
static getDerivedStateFromProps(nextProps, preState) {
    const {match: {params: {instrumentId}}} = nextProps;
    // 此处当传入的instrumentId产生改动的时分,更新state
    if (instrumentId !== preState.instrumentId) {
		//若需求在数据改动后进行其他操作,需求在return前操作!
        return {
            instrumentId: instrumentId,
        };
    }
    return null;    // 不改动,则对于state不进行任何操作
}
②无条件的依据 prop 来更新内部 state,也便是只需有传入 prop 值, 就更新 state

(可是假如只需props值改动,就更新state,其实直接用props的值去进行操作就能够了。)

static getDerivedStateFromProps (props, state) {
    const {match: {params: {instrumentId}}} = nextProps;
    return {
        instrumentId: instrumentId,
    }
}
③getDerivedStateFromProps中运用this指针:

由于getDerivedStateFromProps被界说为静态办法,所以不能够直接运用this.,因而我们需求对类进行实例化,才运用类中界说的办法:

class InstrumentCommand extends PureComponent {
					......
	static getDerivedStateFromProps(nextProps, preState) {
    	const {match: {params: {instrumentId}}} = nextProps;
    	if (instrumentId !== preState.instrumentId) {
      	new InstrumentCommand(nextProps).implementDispatch(instrumentId)
		}
	}
}
					......

6.运用getDerivedStateFromProps的遇到的问题及注意事项:

①回来值问题

getDerivedStateFromProps办法必定要return一个值,假如不需求对state操作,只需return null;即可,不可回来undefined。 当getDerivedStateFromProps()没有清晰回来任何内容时,控制台会输出警告

②生命周期中触发问题

假如在getDerviedStateFromProps中被操作的数据,假如在constructor初始化为null,在render中对其重新赋值,要注意需求在函数中进行判别,否则会导致报错:Cannot read properties of null (reading ‘……’)

原因:当改写页面后,constructor后,生命周期中(见上图)会调用一次getDerviedStateFromProps此刻并没有render()也就没有赋值,因而取到的数据为null。

代码如下:

  static getDerivedStateFromProps(nextProps, preState) {
    const {match: {params: {instrumentId}}} = nextProps;
    const {dispatch, form: {resetFields}} = nextProps;
    const {instance} = preState;
    if (instrumentId !== preState.instrumentId) {
      resetFields();
      dispatch({
        type: 'InstrumentCommandModel/cleanCommandDetail',
      });
	//我在对instance操作时,进行了一次非nul判别。
      if (instance !== null) {
        instance.setValue('');
      }
      return {
        instrumentId: instrumentId,
        editStatus: DETAIL_EDIT_STATUS.ADD,
        commandLine: '',
      }
    }
    return null;
  }

7.static getDerivedStateFromProps()办法中的三类数据:

nextprops:从父组件或父页面跳转时传入的props或当时也更新后的props。

preState:当时页State数据。

new 类名(nextProps):生成一个当时页初始的this指针。能够拜访this数据及办法。

注意:

①生成的是当时页面初始的this指针,假如调用办法,console.log(this.state)输出的是在constructor()中的初始值。假如你想在该函数中操作state数据或许调用目标数据中的办法时,办法如下:
i、调用目标数据中的办法

假如调用目标数据中的办法能够传入preState数据(比方:在此处笔者将state中的instance初始化为null,并在render()中运用CodeMirror组件供给的API将instance赋值为一个供给改动CodeMirror值的目标,笔者需求调用该目标中的办法,因而在static getDerivedStateFromProps()中传入preState去解构该目标,并调用其中供给的办法。)

ii、只改动state数据

假如只改动state数据,getDerivedStateFromProps()自身便是为了return中直接回来更新state

②假如实例化后,打印props为undefined,则在未在constructor()办法中传入props。

牢记: 假如需求在static getDerivedStateFromProps()中运用到大局this中某个目标中的办法**操作数据,必定要将数据界说在state中,而 不要直接界说为下图的this.instance,能够防止许多麻烦!!!

比方上文:(i)中提到的instance目标值的问题。

注意:此种情况下,主张将数据界说在state中,而不要直接this.instance=null在constructor()中界说,由于假如直接this.instance界说,就算在render中赋值后,实例化目标拿到的数据,永远是初始值null。 而在state中界说的话,则只需求判别不为null的时分,就能够拜访到instance目标中的办法。

React新生命周期getDerivedStateFromProps的理解与使用

constructor(props) {//不传入props,实例化后,props未undefined
    super(props);//不传入props,实例化后,props未undefined
    this.instance=null;//由实例化后的目标new 类名(nextProps)打印。
    this.state = {//由preState打印。
     	instrumentId:0,
    }
}