javascript 关于 getDerivedStateFromProps 的思考
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48863450/
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
A thought about getDerivedStateFromProps
提问by Huy Vo
According to this post about what's news in React 16.3, in the next update componentWillReceivePropswill have a replacement and that is getDerivedStateFromProps(the replacement will only happens in 17.0).
根据这篇关于React 16.3 新闻的帖子,在下一次更新componentWillReceiveProps中将有一个替代品,也就是说getDerivedStateFromProps(替代品只会发生在 17.0 中)。
The interesting part is that this brand new, static lifecycle method
有趣的是,这个全新的静态生命周期方法
is called both on initial mounting and on re-rendering of the component, so you can use it instead of creating state based on props in constructor.
在初始安装和重新渲染组件时都会调用它,因此您可以使用它而不是基于构造函数中的 props 创建状态。
I'm getting confused. So from now on should I need to split my constructor and put the create state logic to this new function instead? I mean the logic when you create state first time your component is created and the logic when you create state from API props is not the same. Putting them together in one method seems not very ideal.
我越来越糊涂了。所以从现在开始,我是否需要拆分我的构造函数并将创建状态逻辑放到这个新函数中?我的意思是第一次创建组件时创建状态的逻辑和从 API props 创建状态时的逻辑是不一样的。将它们放在一种方法中似乎不太理想。
And one more thing is that if I choose to create my state from constructor, this new method will still be called anyway. What a jerk!
还有一件事是,如果我选择从构造函数创建我的状态,这个新方法仍然会被调用。真是个混蛋!
What do you think?
你怎么认为?
回答by Agney
Let us say we have a list component, that renders a few list items by supplying a few parameters received from it's parent to the API.
假设我们有一个列表组件,它通过向 API 提供从其父级接收到的一些参数来呈现一些列表项。
- First we initialise
this.state.datavariable to[]. - Then using the props, we perform an API call in
componentDidMount()to assign it tothis.state.data. - Now, these parameterscoming from the parent are subject to change, so you had to repeat the procedure in
componentWillReceiveProps.
- 首先我们将
this.state.data变量初始化为[]。 - 然后使用 props,我们执行一个 API 调用
componentDidMount()以将其分配给this.state.data. - 现在,来自父级的这些参数可能会发生变化,因此您必须在
componentWillReceiveProps.
I think this is the likely scenario that getDerivedStateFromPropsis targeting. Now instead of updating state from props twice, you only need to write it once in the function: getDerivedStateFromProps. As the name suggests, use it when state has to be derived from the props.
我认为这是针对的可能情况getDerivedStateFromProps。现在,您只需在函数中写入一次,而不是从 props 更新状态两次:getDerivedStateFromProps。顾名思义,当 state 必须从 props 派生时使用它。
Points to keep in mind:
要记住的要点:
You still need to set initial state in constructor. The logic for both initial state and deriving state from props can be very different. For example, if you do not initialise the datavariable to []and you are mapping over this.state.datait would fail as the API has not returned the results to be set in getDerivedStateFromPropsyet.
您仍然需要在构造函数中设置初始状态。初始状态和从 props 派生状态的逻辑可能非常不同。例如,如果您没有将data变量初始化为[]并且您正在映射this.state.data它,则会失败,因为 API 尚未返回要设置的结果getDerivedStateFromProps。
Even though getDerivedStateFromPropscan't use this, it works in the same way that this.setStatedoes.
即使getDerivedStateFromProps不能使用this,它的工作方式也是一样的this.setState。
That is, if you return
也就是说,如果你返回
{
data: response.data
}
it wouldn't update the other state variables that you have set in constructor. Also you have an option to return nullto signify no change.
它不会更新您在构造函数中设置的其他状态变量。您还可以选择返回null以表示没有变化。
From:
从:
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
externalData: []
}
}
componentWillMount() {
asyncLoadData(this.props.someId).then(externalData =>
this.setState({ externalData })
);
}
componentWillReceiveProps() {
asyncLoadData(this.props.someId).then(externalData =>
this.setState({ externalData })
);
}
}
To:
到:
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
externalData: []
}
}
static deriveStateFromProps(props, state, prevProps) {
if (prevProps === null || props.someValue !== prevProps.someValue) {
return {
derivedData: computeDerivedState(props)
};
}
// Return null to indicate no change to state.
return null;
}
}
Note: I'm just noting an instance from pure React perspective.
注意:我只是从纯 React 角度注意到一个实例。
Also read You Probably Don't Need Derived Statefrom React Blog.
回答by tomhughes
The key difference is that in React 16 componentWillReceivePropsis not called on the inital render, only when new props are received. This means you would in your case, create derived state on first load in the constructor, then use componentWillReceivePropson update.
关键的区别在于,在 React 16 中componentWillReceiveProps不会在初始渲染时调用,只有在接收到新的 props 时才会调用。这意味着在您的情况下,您将在构造函数中首次加载时创建派生状态,然后在更新时使用componentWillReceiveProps。
With the new getDerivedStateFromPropsthis logic can be written in this function only, as it runs on both inital mount andupdates.
使用新的getDerivedStateFromProps这个逻辑只能写在这个函数中,因为它在初始安装和更新上运行。
React doesn't call componentWillReceiveProps() with initial props during mounting. It only calls this method if some of component's props may update. Calling this.setState() generally doesn't trigger componentWillReceiveProps().
React 在挂载期间不会使用初始道具调用 componentWillReceiveProps()。仅当某些组件的 props 可能更新时才调用此方法。调用 this.setState() 通常不会触发 componentWillReceiveProps()。
In regards to your question regarding API'sto me that would be dependent on how the component is set up, seems to me like it would be logical to make the API call in a parent component, that way you can control how the props are passed down and make the component receiving the props as dumb as possible. State can still be set in a method after making the API call.
关于您关于 API 的问题,这取决于组件的设置方式,在我看来,在父组件中进行 API 调用是合乎逻辑的,这样您就可以控制道具的传递方式并使接收 props 的组件尽可能的愚蠢。在进行 API 调用后,仍然可以在方法中设置状态。
As Dan Abramov states, passing props to state is usually a bad idea, this function will be used infrequently is designed to be used when your state depends on how props change over time.
正如 Dan Abramov 所说,将 props 传递给 state 通常是一个坏主意,这个函数将很少使用,旨在当你的 state 取决于 props 如何随时间变化时使用。
Props to state as an anti-practiceand a potential use case.

