为什么在 setState 之后调用 getDerivedStateFromProps?

IT技术 reactjs getderivedstatefromprops
2021-05-03 12:54:54

React 引入了新的静态方法getDerivedStateFromProps(props, state),它在每个渲染方法之前调用,但为什么呢?在props更改后调用它对我来说很有意义,但在setState它没有之后,也许我错过了一些东西。

datePicker根据我公司的要求创建了一个组件,组件日期由props控制。我在组件中有以下状态。

selectedDate: number;
selectedMonth: number;
selectedYear: number;
currentMonth: number;
currentYear: number;
view: string;

selected 表示选定的日期,该日期源自 date 属性,currentMonthcurrentYear表示当前日历视图中的月份和年份。

如果datefrom prop 发生变化selected*currentMonthcurrentYear应该相应地改变。为此,我正在使用getDerivedStateFromProps但假设用户单击月份名称将日历视图切换为月份(而不是显示月份的日期名称),该函数currentMonth使用 setState更新此日期,但日期props与之前(包含上个月)应该,但是getDerivedStateFromProps被调用并且 currentMonth 再次与之前相同而不是改变。

是的,我创建了一个额外的变量state来跟踪是否getDerivedStateFromProps被调用,setState但我认为这不是正确的方法。

要么我做错了什么,要么遗漏了什么,或者getDerivedStateFromProps不应该在setState. 可能我做错了什么。

4个回答

getDerivedStateFromProps每当接收到新的 propssetStateforceUpdate时,钩子的工作方式

在 的版本中16.3,React 不会getDerivedStateFromProps在任何时候setState被使用。但是他们在以 开头的版本中对其进行了改进 16.4,因此无论何时setState调用 ,getDerivedStateFromProps都会被挂钩。

这是从React 生命周期图中提取的图像

16.3

在此处输入图片说明

^16.4

在此处输入图片说明


所以,什么时候getDerivedStateFromProps通过正确检查 props 和 state来挂钩你决定下面是一个例子:

static getDerivedStateFromProps (props, state) {
  // check your condition when it should run?
  if(props.currentMonth != state.currentMonth) {
    return {
      currentMonth: state.currentMonth
    }
  }
  // otherwise, don't do anything
  else {
   return null
  }
}

我做了这样的事情

constructor(props) {
    super(props);
    this.state = {
        expanded: props.expanded,
        ownUpdate: false
    }
}

static getDerivedStateFromProps(props, state) {
    if (state.ownUpdate) {
        return {
            expanded: state.expanded,
            ownUpdate: false
        };
    } else if (props.expanded !== state.expanded) {
        return {
            expanded: props.expanded
        };
    }
    return null;
}

toggle() {
    this.props.onAftePress(this.state.expanded, this.props.index);
    this.setState({
        expanded: !this.state.expanded,
        ownUpdate: true
    })
}

我也遇到了那个问题。所以我设置了另一个变量来检查是第一次收到的props。

this.state={flag:true}

getderivedstatefromprops 中

static getderivedstatefromprops(props, state){
   if(props.<*propName*> && flag){
      return({ props.<*propName*>, flag:false})
   }
}

如果你想使用多个 props 值,你需要相应地设置你的 if 语句(或任何其他逻辑)。

你的问题本身就有答案。“在每个渲染方法之前调用”。每当您执行setStaterender方法时,都会调用方法。

我建议你解除状态变量currentMonthcurrentYear组件的父,并通过他们的props与其他三个一起。您还可以将更改处理程序作为props传递并从子级调用它。

在初始render- currentMonth并且currentYear可以设置为null,以便您可以拥有显示默认内容的逻辑。当有人选择月份名称时,您可以调用changeHandler将传递新props来自父级。现在getderivedstatefromprops你不再有currentMonthand currentYearas `null 这样你就知道月份已经改变了。