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


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

官方文件说:

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

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

如果API调用很慢,那么 setState 将是异步和 componentWillMount 已经返回然后我将能够setState并且应该重新渲染。

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


5611
2018-04-01 08:26


起源

进行API调用 componentWillMount 如果您需要这个并不是坏主意,但是在调用第一个渲染之前,不可能从API获得响应并设置适当的状态。 - elmeister
@elmeister - 如果您的API通过缓存层,您可以同步获取查询的缓存结果。 - Jules
相关文章 这里。 - RBT


答案:


1。 componentWillMount 并重新渲染 

比较这两个 componentWillMount 方法。
一个导致额外的重新渲染,一个没有

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 '});
  })
}




2.在哪里调用API调用?

componentWillMount () {
  // Is triggered on server and on client as well.
  // Server won't wait for completion though, nor will be able to trigger re-render
  // for client.
  fetch('...')
}

componentDidMount () {
  // Is triggered on client, but never on server.
  // This is a good place to invoke API calls.
  fetch('...')
} 

如果要在服务器上进行渲染,并且组件确实需要数据进行渲染,则应在组件外部获取(并等待完成)并通过props传递数据,然后将组件渲染为字符串。


12
2018-04-01 10:58





ComponentWillMount

现在那个了 道具和国家都设定了,我们终于进入了生命周期方法的领域

这意味着React期待 state 可用 render 函数将被调用next,如果任何提到的状态变量丢失,代码可能会中断,如果有的话 ajax


构造函数

这是您定义的地方。

所以调用ajax不会更新任何状态的值,因为ajax是异步的,构造函数不会等待响应。理想情况下,您应该使用构造函数进行设置 默认/初始 值。


理想情况下,这些函数应该是纯函数,仅取决于参数。瞻 ajax 带来副作用。

是的,功能取决于 state 和使用 this.setState 可以带给你这样的问题(您已在状态中设置值,但在下一个被调用函数中的状态中缺少值)。

这使代码变得脆弱。如果您的API非常快,您可以将此值作为参数传递,并在组件中检查此arg是否可用。如果是,请初始化您的状态。如果没有,请将其设置为默认值。此外,在ajax的成功功能中,您可以检查 ref 这个组件。如果存在,则呈现组件,您可以调用它 state运用 setState  或任何 setter首选)功能。

还记得,当你说的时候 API调用非常快,您的服务器和处理可能处于最佳速度,但您无法确定网络。


3
2018-04-01 08:48



我不是专家,所以有可能,我可能犯了错误。如果有任何不一致之处,请与您的投票一起评论。 - Rajesh
但是,如果我在构造函数中放置了一些不会破坏渲染的默认状态,该怎么办呢?此外,在渲染返回后调用setState,因为它将被React视为事件。怎么样 componentWillMount 会造成困难吗? - Ajay Gaur
这不是语法错误。它只是编码实践。 - Devinder Suthwal


如果你只需要在第一次运行时只需要数据,如果你对它没问题。您可以通过调用回调来同步setState。

例如:

componentWillMount(){
    this.setState({
                sessionId: sessionId,                
            }, () => {
                if (this.state.hasMoreItems = true) {
                    this.loadItems()   // do what you like here synchronously 
                }
            });
}

0
2018-03-19 07:51