我可以在React中调用componentWillMount中的API吗?

时间:2017-04-01 08:26:28

标签: javascript reactjs

我正在做最后一年的反应。我们遵循的约定是在componentDidMount中进行API调用,在数据到来之后获取数据和setState。这将确保组件已安装,设置状态将导致重新呈现组件,但我想知道为什么我们不能在componentWillMountconstructor中设置State

官方文件说:

  

在安装发生之前立即调用componentWillMount()。它   在render()之前调用,因此在此方法中设置状态   不会触发重新渲染。避免引入任何副作用或   订阅此方法。

它说setting state in this method will not trigger a re-rendering,这是我在进行API调用时不想要的。如果我能够在componentWillMountconstructor中获取数据并且能够设置状态(假设API调用非常快)并且数据存在于第一个渲染中,为什么会我想要重新渲染一下?

如果API调用很慢,那么setState将是异步的并且componentWillMount已经返回,那么我将能够设置状态并且应该进行重新渲染。

总的来说,我很困惑为什么我们不应该在构造函数或componentWillMount中进行API调用。在这种情况下,有人能真正帮助我了解反应是如何起作用的吗?

3 个答案:

答案 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 
                }
            });
}