2022年前端React的100道面试题的第8题:getDerivedStateFromProps方法
问题
关于 static getDerivedStateFromProps 方法的理解正确的有哪些?
选项
A 会在调用 render 方法之后调用,并且在初始挂载及后续更新时都会被调用。
B 它应返回一个对象来更新 state,如果返回 null
则不更新任何内容。
C 存在只有一个目的:让组件在 props 变化时更新 state。
D 是在16.4 版本新增的,用于替代 shouldComponentUpdate 生命周期。
答案
B、C
纠错:
A 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
D 此生命周期是在 16.3 版本新增的,用于替代 componentWillReceiveProps 生命周期。 在 16.4 版本进行了优化,无论props还是state的修改都会触发的渲染此生命周期,在上一个版本只会在 props 触发渲染时更新。
(16.4 的优化后,便与 UNSAFE_componentWillReceiveProps
的执行时机不同,后者仅在父组件重新渲染时触发,而不是在内部调用 setState
时。)
解答
此方法无权访问组件实例。
static getDerivedStateFromProps
生命周期是接受 props 和 state 参数的纯函数。
它的执行顺序
-
constructor()
-
static getDerivedStateFromProps()
-
render()
-
componentDidMount()
触发此生命周期的时机
-
state 修改时触发的渲染时;
-
props 修改时触发的渲染时;
-
父组件重新渲染时;
此生命周期和 shouldComponentUpdate(props, state)
的区别
前置控制 state 的修改,后置控制 render 是否允许被执行。
此生命周期和 UNSAFE_componentWillReceiveProps(nextProps: any): void
的区别
在 static getDerivedStateFromProps()
后,UNSAFE_componentWillReceiveProps
将不会再执行,且后置不会再设置 setState() 触发。
作用 state 的方式
如果不做任何返回,或者返回空对象,都不会对 state 有任何影响。因为它返回的是一个干净的对象,会 merge 到 state 对象上作为最新的数据状态值。从 TS 函数定义检查考虑,如果有逻辑中的 return,建议在函数最后提供一个默认返回值 return null
。
使用方式
当判断 props 是否发生修改时,需要先存储 props 的值,然后对比上次和本次的 props 是否有差异,如果有差异才重新渲染此组件。
class EmailInput extends Component {
state = {
email: this.props.email,
preEmail: this.props.email,
};
static getDerivedStateFromProps(props, state) {
if (props.email !== state.preEmail) {
return { email: props.email, preEmail: props.email };
}
return null
}
render() {
return <input onChange={this.handleChange} value={this.state.email} />;
}
handleChange = event => {
this.setState({ email: event.target.value });
};
}
官方提醒
旧的 componentWillReceiveProps
和新的 getDerivedStateFromProps
方法都会给组件增加明显的复杂性。为了比对 props 的变化,往往需要用 props 中的属性作为 state 作为初始化,因为上面的触发时机,会导致覆盖组件内部在 state 的值。这样做会导致 state 后没有正确渲染。
资料
来源