如何使用生命周期方法 getderiedStateFromProps 而不是组件 WillReceiveProps

看起来 componentWillReceiveProps将在即将发布的版本中被完全淘汰,这有利于一种新的生命周期方法 getDerivedStateFromProps: ()

经过检查,它看起来像你现在无法作出一个直接的比较之间的 this.propsnextProps,就像你可以在 componentWillReceiveProps。还有别的办法吗?

同时,它现在返回一个对象。我假设返回值本质上是 this.setState对吗?

下面是我在网上找到的一个例子: 由道具/状态衍生的状态

之前

class ExampleComponent extends React.Component {
state = {
derivedData: computeDerivedState(this.props)
};


componentWillReceiveProps(nextProps) {
if (this.props.someValue !== nextProps.someValue) {
this.setState({
derivedData: computeDerivedState(nextProps)
});
}
}
}

之后

class ExampleComponent extends React.Component {
// Initialize state in constructor,
// Or with a property initializer.
state = {};


static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.someMirroredValue !== nextProps.someValue) {
return {
derivedData: computeDerivedState(nextProps),
someMirroredValue: nextProps.someValue
};
}


// Return null to indicate no change to state.
return null;
}
}
185764 次浏览

关于删除 componentWillReceiveProps: 您应该能够处理它的使用与 getDerivedStateFromPropscomponentDidUpdate的组合,参见 React 博客文章的例子迁移。是的,getDerivedStateFromProps返回的对象类似于传递给 setState的对象更新状态。

如果你真的需要一个道具的旧价值,你总是可以缓存它在你的状态,像这样的东西:

state = {
cachedSomeProp: null
// ... rest of initial state
};


static getDerivedStateFromProps(nextProps, prevState) {
// do things with nextProps.someProp and prevState.cachedSomeProp
return {
cachedSomeProp: nextProps.someProp,
// ... other derived state properties
};
}

任何不影响状态的东西都可以放在 componentDidUpdate中,甚至还有一个 getSnapshotBeforeUpdate用于非常低级的东西。

更新: 为了了解新的(和旧的)生命周期方法,反应-生命周期-可视化器包可能会有所帮助。

正如我们 最近发表在 React 博客上的一篇文章,在绝大多数情况下 你根本不需要 getDerivedStateFromProps

如果你只是想计算一些派生数据,要么:

  1. 就在 render里面
  2. 或者,如果重新计算代价很高,可以使用类似 memoize-one的制表助手。

下面是最简单的“事后”例子:

import memoize from "memoize-one";


class ExampleComponent extends React.Component {
getDerivedData = memoize(computeDerivedState);


render() {
const derivedData = this.getDerivedData(this.props.someValue);
// ...
}
}

查看 这篇博客文章的这一部分了解更多信息。

正如 Dan Abramov 所说

在渲染室内完成

实际上,我们使用这种方法与制表符一对任何类型的代理支持状态计算。

我们的代码是这样的

// ./decorators/memoized.js
import memoizeOne from 'memoize-one';


export function memoized(target, key, descriptor) {
descriptor.value = memoizeOne(descriptor.value);
return descriptor;
}


// ./components/exampleComponent.js
import React from 'react';
import { memoized } from 'src/decorators';


class ExampleComponent extends React.Component {
buildValuesFromProps() {
const {
watchedProp1,
watchedProp2,
watchedProp3,
watchedProp4,
watchedProp5,
} = this.props
return {
value1: buildValue1(watchedProp1, watchedProp2),
value2: buildValue2(watchedProp1, watchedProp3, watchedProp5),
value3: buildValue3(watchedProp3, watchedProp4, watchedProp5),
}
}


@memoized
buildValue1(watchedProp1, watchedProp2) {
return ...;
}


@memoized
buildValue2(watchedProp1, watchedProp3, watchedProp5) {
return ...;
}


@memoized
buildValue3(watchedProp3, watchedProp4, watchedProp5) {
return ...;
}


render() {
const {
value1,
value2,
value3
} = this.buildValuesFromProps();


return (
<div>
<Component1 value={value1}>
<Component2 value={value2}>
<Component3 value={value3}>
</div>
);
}
}

它的好处是您不需要在 getDerivedStateFromPropscomponentWillReceiveProps中编写大量的比较样板代码,并且您可以在构造函数中跳过复制粘贴初始化。

注意:

这种方法只用于代理支持状态,以防您有一些内部状态逻辑,它仍然需要在组件生命周期中处理。

只要您想在呈现之前更新状态,并使用道具条件更新状态,就可以使用 getderiedStateFromProps

通过道具值的帮助更新 stats 值

https://www.w3schools.com/REACT/react_lifecycle.asp#:~:text=Lifecycle%20of%20Components,Mounting%2C%20Updating%2C%20and%20Unmounting