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

IT技术 javascript reactjs
2021-03-29 09:09:05

我正在研究过去 1 年的react。我们遵循的约定是在 中进行 API 调用componentDidMount,在数据到来后获取数据和 setState。这将确保组件已安装并且设置状态将导致重新渲染组件但我想知道为什么我们不能在componentWillMountconstructor

官方文档说:

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

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

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

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

3个回答

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 传递数据,然后将组件渲染为字符串。

组件挂载

现在props 和 state 都设置好了,我们终于进入了生命周期方法的领域

这意味着 React 期望state可用,因为render接下来将调用函数,并且如果缺少任何提到的状态变量,代码可能会中断,这可能发生在ajax.


构造函数

这是您定义的地方。

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


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

是的,函数依赖state和使用this.setState会给你带来这样的问题(你在状态中设置了值,但在下一个调用的函数中状态中缺少值)。

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

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

但是如果我在构造函数中放置了一些不会破坏渲染的默认状态呢?setState 在渲染返回后也会被调用,因为它会被 React 视为一个事件。怎么componentWillMount会造成困难?
2021-06-15 09:09:05
我不是专家,所以有可能,我可能犯了错误。如果有任何不一致之处,请与您的投票一起发表评论。
2021-06-20 09:09:05

如果您只在第一次运行时只需要数据,并且您对此感到满意。您可以通过调用回调同步 setState。

例如:

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