React引入了新的静态方法getDerivedStateFromProps(props, state)
,它在每个渲染方法之前调用,但为什么呢?在改变道具之后调用它对我有意义,但在setState
之后它没有,也许我错过了一些东西。
我根据我公司的要求创建了一个datePicker
组件,在组件日期由prop支持。我在组件中有以下状态。
selectedDate: number;
selectedMonth: number;
selectedYear: number;
currentMonth: number;
currentYear: number;
view: string;
selected表示从date prop和currentMonth
派生的选定日期,currentYear
表示当前日历视图中的月份和年份。
如果来自道具的date
改变selected*
,则应相应更改currentMonth
和currentYear
。为此,我使用getDerivedStateFromProps
但是让用户点击月份名称将日历视图切换到月份(而不是显示月份的日期名称),该函数使用setState更新currentMonth
,但是日期是道具是与之前(包含前一个月)相同,但应调用getDerivedStateFromProps
,而currentMonth再次与之前相同而不是更改。
我在state
中创建了一个额外的变量,以跟踪getDerivedStateFromProps
是否由于setState
被调用,但我不认为这是正确的方法。
无论是我做错了什么或丢失的东西或getDerivedStateFromProps
不应该在setState
后调用。可能我做错了什么。
我也遇到了这个问题。所以我设置另一个变量来检查是第一次收到道具。
this.state={flag:true}
在getderivedstatefromprops
static getderivedstatefromprops(props, state){
if(props.<*propName*> && flag){
return({ props.<*propName*>, flag:false})
}
}
如果你想使用多个道具值,你需要相应地设置你的if语句(或任何其他逻辑)。
每当收到新的props,setState和forceUpdate时,getDerivedStateFromProps
钩子的工作方式。
在16.3
的版本中,只要使用getDerivedStateFromProps
,React就不会影响setState
。但是他们在从16.4
开始的版本中对它进行了改进,因此每当setState
被称为getDerivedStateFromProps
时,它就会被吸引。
这是从React lifecycle diagram提取的图像:
因此,你可以通过正确检查道具和状态来挂钩getDerivedStateFromProps
。这是一个例子:
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
})
}
你的问题本身就有答案。 “在每个渲染方法之前调用它”。每当你做一个setState
时,将调用render
方法。
我建议你将状态变量currentMonth
和currentYear
提升到父组件,并将它们作为prop与其他三个一起传递。您还可以将更改处理程序作为prop传递,并从子项中调用它。
在最初的render
- currentMonth
和currentYear
可以设置为null
,这样你就可以拥有显示默认内容的逻辑。当有人按月名称时,你可以从父母那里调用changeHandler
,这将传递新的道具。现在在getderivedstatefromprops
你不再有currentMonth
和currentYear
为'null所以你知道这个月已经改变了。