【React】React 的 getDerivedStateFromProps 生命周期 究竟有啥用 ?

随着react v16.3版本的发布,

最大的变动莫过于生命周期去掉了以下三个

componentWillMount
componentWillReceiveProps
componentWillUpdate
同时为了弥补失去上面三个周期的不足又加了两个

static getDerivedStateFromProps
getSnapshotBeforeUpdate
如下图:
【React】React 的  getDerivedStateFromProps 生命周期 究竟有啥用 ?

新的静态生命周期方法 getDerivedStateFromProps 是根据props来派生出新的state

前段时间在使用 getDerivedStateFromProps 时,只是机械的用它和 componentDidUpdate 来替换 componentWillReceiveProps,已达到通过修改props,来修改state的作用,比如下面这个例子:

// Before

class ExampleComponent extends React.Component {

state = {

externalData: null,

};

componentDidMount() {

// this.props.id === undefined

this._loadData(this.props.id);

}

componentWillReceiveProps(nextProps) {

//当某个props中的值发生变化时(此处是id属性)

if (nextProps.id !== this.props.id) {

//初始化state中的externalData值为null

this.setState({externalData: null});

//基于新的id属性,异步获取数据,并在完成时设置externalData的值

this._loadData(nextProps.id);

}

}

render() {

if (this.state.externalData === null) {

// Render loading state ...

} else {

// Render real UI ...

}

}

_loadData(id) {

if (!id) {return;}

loadData(id).then(

externalData => {

this.setState({externalData});

}

);

}

}

改写之后:

// After Wrong

class ExampleComponent extends React.Component {

state = {

externalData: null,

prevId: this.props.id

};

static getDerivedStateFromProps(nextProps, prevState) {

// Store prevId in state so we can compare when props change.

// Clear out previously-loaded data (so we don't render stale stuff).

if (nextProps.id !== prevState.prevId) {

return {

externalData: null,

prevId: nextProps.id,

};

}

// No state update necessary

return null;

}

componentDidUpdate(prevProps, prevState) {

if (this.state.externalData === null) {

this._loadData(this.props.id);

}

}

componentDidMount() {

this._loadData(this.props.id);

}

render() {

if (this.state.externalData === null) {

// Render loading state ...

} else {

// Render real UI ...

}

}

_loadData(id) {

if (!id) {return;}

loadData(id).then(

externalData => {

this.setState({externalData});

}

);

}

}

getDerivedStateFromProps 存在只为了一个目的。它让组件在 props 发生改变时更新它自身的内部 state。 一个常规的准则,应该保守地使用 derived state。

看了一下:https://reactjs.org/blog/2018... 中有提到两个使用 getDerivedStateFromProps 的反模式:

无条件地将 prop 复制给 state
当 props 改变时清除 state,使 props 和 state 中的值,保持一致
这个例子比较符合第二种情况。就是为了比较id是否更新,把props中的id,存到了state 中 prevId。
并且 在 componentDidUpdate 的时候, 根据 state 中的 externalData 是否改变来判断是否需要异步加载新的数据。

这样写也没有错误,但是没有必要这样写,这样写反而增加了程序的复杂程度。

// Right

class ExampleComponent extends React.Component {

state = {

externalData: null,

};

componentDidUpdate(prevProps, prevState) {

if (this.props.id && this.props.id !== prevProps.id) {

this._loadData(this.props.id);

}

}

componentDidMount() {

this._loadData(this.props.id);

}

render() {

if (this.state.externalData === null) {

// Render loading state ...

} else {

// Render real UI ...

}

}

_loadData(id) {

if (!id) {return;}

loadData(id).then(

externalData => {

this.setState({externalData});

}

);

}

}

因为上面的例子属于异步的更新,所以直接使用 componentDidUpdate 来确保是基于正确的 props 来更新 state 足以。

对不受控组件,如果你在一个特殊的 prop (通常是 ID)改变时试图重置 state,你有一些选择:

推荐:重置所有内部 state,使用 key 属性
替代方案1:仅重置确定的 state 字段,监听特定属性的变化(例如: props.id)。
替代方案2:你也可以考虑使用 refs 调用一个命令式实例方法。

回答

当我尝试把加了 getDerivedStateFromProps 的代码合并到主分支,代码审查员没有给过我一次机会... [getDerivedStateFromProps] 他到底有什么用呢 (╯°□°)╯︵┻━┻

以上是 【React】React 的 getDerivedStateFromProps 生命周期 究竟有啥用 ? 的全部内容, 来源链接: utcz.com/a/75798.html

回到顶部