我正在做最后一年的反应。我们遵循的约定是在componentDidMount
中进行API调用,在数据到来之后获取数据和setState。这将确保组件已安装,设置状态将导致重新呈现组件,但我想知道为什么我们不能在componentWillMount
或constructor
中设置State
官方文件说:
在安装发生之前立即调用componentWillMount()。它 在render()之前调用,因此在此方法中设置状态 不会触发重新渲染。避免引入任何副作用或 订阅此方法。
它说setting state in this method will not trigger a re-rendering
,这是我在进行API调用时不想要的。如果我能够在componentWillMount
或constructor
中获取数据并且能够设置状态(假设API调用非常快)并且数据存在于第一个渲染中,为什么会我想要重新渲染一下?
如果API调用很慢,那么setState
将是异步的并且componentWillMount
已经返回,那么我将能够设置状态并且应该进行重新渲染。
总的来说,我很困惑为什么我们不应该在构造函数或componentWillMount中进行API调用。在这种情况下,有人能真正帮助我了解反应是如何起作用的吗?
答案 0 :(得分:18)
<强> 1。 def RecLinearSearch(lyst,number):
found = False
index = len(lyst)-1
if lyst[index] == number:
found = True
return found
elif index<len(lyst)-1:
index +=1
return RecLinearSearch(lyst[index:],number)
return found
print(RecLinearSearch([1,4,5,65,44],55))
并重新呈现
比较这两种componentWillMount
方法
一个导致额外的重新渲染,一个不是
componentWillMount
。
。
。
的 2。在哪里调用API调用?
componentWillMount () {
// This will not cause additional re-render
this.setState({ name: 'Andrej '});
}
componentWillMount () {
fetch('http://whatever/profile').then(() => {
// This in the other hand will cause additional rerender,
// since fetch is async and state is set after request completes.
this.setState({ name: 'Andrej '});
})
}
如果你在服务器上渲染并且你的组件确实需要渲染数据,你应该在组件之外获取(并等待完成)并通过props传递数据并在之后将组件渲染为字符串。
答案 1 :(得分:5)
<强> ComponentWillMount 强>
现在道具和状态已设置,我们终于进入了生命周期方法领域
这意味着React期望state
可用,因为render
函数将被调用next,如果ajax
的情况下可能出现任何提到的状态变量,代码可能会中断。< / p>
<强> Constructor 强>
这是您定义的地方。
因此,调用ajax不会更新任何状态的值,因为ajax是异步的,构造函数不会等待响应。理想情况下,您应该使用构造函数来设置 default / initial 值。
理想情况下,这些函数应该是纯函数,仅取决于参数。使ajax
带来副作用。
是的,函数依赖于state
并且使用this.setState
可以为您带来这样的问题(您已在状态中设置值,但在下一个调用的函数中的状态中缺少值)
这会使代码变得脆弱。如果您的API非常快,您可以将此值作为参数传递,并在组件中检查此arg是否可用。如果是,请用它初始化。如果没有,请将其设置为默认值。此外,在ajax的成功功能中,您可以检查此组件的ref
。如果存在,则呈现组件,您可以使用state
或任何setState
(首选)函数调用其setter
。
还要记住,当你说 API调用真的很快时,你的服务器和处理可能处于最佳速度,但你无法确定网络。
答案 2 :(得分:0)
如果您只需要在第一次运行时只需要数据,并且如果您对此感到满意。您可以通过调用回调来同步setState。
例如:
componentWillMount(){
this.setState({
sessionId: sessionId,
}, () => {
if (this.state.hasMoreItems = true) {
this.loadItems() // do what you like here synchronously
}
});
}