根据这篇关于what's news in React 16.3的帖子,在下一次更新中componentWillReceiveProps
将有一个替换,即getDerivedStateFromProps
(替换只发生在17.0)。
有趣的是,这是一种全新的静态生命周期方法
在初始安装和重新渲染时都会调用组件,所以你可以使用它而不是基于道具创建状态 在构造函数中。
我感到困惑。所以从现在开始我应该拆分我的构造函数并将创建状态逻辑放到这个新函数中吗?我的意思是当你第一次创建组件创建状态时的逻辑,以及从API props创建状态时的逻辑是不一样的。将它们放在一个方法中似乎不太理想。
还有一件事是,如果我选择从构造函数创建我的状态,那么仍然会调用这个新方法。真是个混蛋!
您怎么看?
答案 0 :(得分:10)
我们假设我们有一个列表组件,它通过提供从API的父级接收的一些参数来呈现一些列表项。
this.state.data
变量初始化为[]
。componentDidMount()
中执行API调用,将其分配给this.state.data
。 componentWillReceiveProps
中重复此过程。 我认为这是getDerivedStateFromProps
定位的可能情况。现在,您只需要在函数中编写一次,而不是从props更新两次状态:getDerivedStateFromProps
。顾名思义,当状态必须来自道具时,使用。
要记住的要点:
您仍需要在构造函数中设置初始状态。初始状态和从道具派生状态的逻辑可能非常不同。例如,如果您没有将data
变量初始化为[]
并且您要映射this.state.data
,那么它将失败,因为API尚未返回要在{{1}中设置的结果尚未。
尽管getDerivedStateFromProps
无法使用getDerivedStateFromProps
,但它的工作方式与this
相同。
也就是说,如果你返回
this.setState
它不会更新您在构造函数中设置的其他状态变量。您还可以选择返回{
data: response.data
}
表示没有变化。
自:
null
要:
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 })
);
}
}
注意:我只是从纯粹的React角度注意一个实例。
另请阅读React Blog中的You Probably Don't Need Derived State。
答案 1 :(得分:6)
关键区别在于React 16 componentWillReceiveProps 不会在初始渲染中调用,只有在收到新道具时才会调用。这意味着在您的情况下,您将在构造函数中首次加载时创建派生状态,然后在更新时使用 componentWillReceiveProps 。
使用新的 getDerivedStateFromProps ,此逻辑只能在此函数中编写,因为它在初始安装和更新时运行。
React不会使用初始道具调用componentWillReceiveProps() 在安装过程中它只调用了一些组件的方法 道具可能会更新。调用this.setState()通常不会触发 componentWillReceiveProps()。
关于我对API的问题对我来说将取决于组件的设置方式,在我看来,在一个API调用中是合乎逻辑的。父组件,通过这种方式,您可以控制道具的传递方式,并使组件尽可能地接收道具。在进行API调用之后,仍然可以在方法中设置State。
正如丹·阿布拉莫夫所说,将道具传递给国家通常是一个坏主意,这个功能将不经常使用,旨在当你的状态取决于道具如何随时间变化时使用。