Javascript 如何使用生命周期方法 getDerivedStateFromProps 而不是 componentWillReceiveProps
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49617486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use lifecycle method getDerivedStateFromProps as opposed to componentWillReceiveProps
提问by Andrew
It looks like componentWillReceivePropsis going to be completely phased out in coming releases, in favor of a new lifecycle method getDerivedStateFromProps:static getDerivedStateFromProps().
看起来componentWillReceiveProps将在即将发布的版本中完全淘汰,取而代之的是一种新的生命周期方法getDerivedStateFromProps:static getDerivedStateFromProps()。
Upon inspection, it looks like you are now unable to make a direct comparison between this.propsand nextProps, like you can in componentWillReceiveProps. Is there any way around this?
经过检查,您现在似乎无法在this.props和之间进行直接比较nextProps,就像在 中一样componentWillReceiveProps。有没有办法解决?
Also, it now returns an object. Am I correct to assume that the return value is essentially this.setState?
此外,它现在返回一个对象。我假设返回值本质上是正确的this.setState吗?
Below is an example I found online: State derived from props/state.
下面是我在网上找到的一个例子:State衍生自 props/state。
Before
前
class ExampleComponent extends React.Component {
state = {
derivedData: computeDerivedState(this.props)
};
componentWillReceiveProps(nextProps) {
if (this.props.someValue !== nextProps.someValue) {
this.setState({
derivedData: computeDerivedState(nextProps)
});
}
}
}
After
后
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;
}
}
采纳答案by Oblosys
About the removal of componentWillReceiveProps: you should be able to handle its uses with a combination of getDerivedStateFromPropsand componentDidUpdate, see the React blog postfor example migrations. And yes, the object returned by getDerivedStateFromPropsupdates the state similarly to an object passed to setState.
有关删除的componentWillReceiveProps:你应该能够与组合来处理它的用途getDerivedStateFromProps和componentDidUpdate,看到的阵营博客文章,例如迁移。是的,由 返回的对象getDerivedStateFromProps更新状态类似于传递给 的对象setState。
In case you really need the old value of a prop, you can always cache it in your state with something like this:
如果你真的需要一个 prop 的旧值,你总是可以用这样的东西将它缓存在你的状态中:
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
};
}
Anything that doesn't affect the state can be put in componentDidUpdate, and there's even a getSnapshotBeforeUpdatefor very low-level stuff.
任何不影响状态的东西都可以放进去componentDidUpdate,甚至还有一个getSnapshotBeforeUpdate用于非常低级的东西。
UPDATE: To get a feel for the new (and old) lifecycle methods, the react-lifecycle-visualizerpackage may be helpful.
更新:要了解新的(和旧的)生命周期方法,react-lifecycle-visualizer包可能会有所帮助。
回答by Dan Abramov
As we recently posted on the React blog,in the vast majority of cases you don't need getDerivedStateFromPropsat all.
正如我们最近发布的博客作出反应,在绝大多数情况下,你并不需要getDerivedStateFromProps在所有。
If you just want to compute some derived data, either:
如果您只想计算一些派生数据,可以:
- Do it right inside
render - Or, if re-calculating it is expensive, use a memoization helper like
memoize-one.
- 在里面做
render - 或者,如果重新计算它很昂贵,请使用像
memoize-one.
Here's the simplest "after" example:
这是最简单的“之后”示例:
import memoize from "memoize-one";
class ExampleComponent extends React.Component {
getDerivedData = memoize(computeDerivedState);
render() {
const derivedData = this.getDerivedData(this.props.someValue);
// ...
}
}
Check out this section of the blog postto learn more.
查看博客文章的这一部分以了解更多信息。
回答by mpospelov
As mentioned by Dan Abramov
正如丹·阿布拉莫夫所说
Do it right inside render
就在渲染里面做
We actually use that approach with memoise one for any kind of proxying props to state calculations.
我们实际上将这种方法与 memoise one 一起用于任何类型的代理道具以进行状态计算。
Our code looks this way
我们的代码看起来像这样
// ./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>
);
}
}
The benefits of it are that you don't need to code tons of comparison boilerplate inside getDerivedStateFromPropsor componentWillReceivePropsand you can skip copy-paste initialization inside a constructor.
它的好处是您不需要在内部编写大量比较样板,getDerivedStateFromProps或者componentWillReceiveProps您可以跳过构造函数内部的复制粘贴初始化。
NOTE:
笔记:
This approach is used only for proxying the props to state, in case you have some inner state logic it still needs to be handled in component lifecycles.
这种方法仅用于将 props 代理到 state,如果您有一些内部状态逻辑,它仍然需要在组件生命周期中处理。

