在componentDidMount()上设置状态


73

我知道将状态设置为打开是一种反模式,componentDidMount应该将状态设置为打开,componentWillMount但是假设我想将li标记数量的长度设置为状态。在那种情况下,我无法将状态设置为on,componentWillMount因为li在该阶段可能未安装标签。那么,这里最好的选择是什么?如果将状态设置为开启,会componentDidMount好吗?


2
您是否li根据某些道具(或数据)渲染标签?你能用data.length吗?
戴文·崔顿,2016年

简单地说。说我有4个li标签,我想获取它们的数量,以便我的maxNumber状态为4。但是,我确实li根据一些道具(或数据)渲染了标签。
Nirmalya Ghosh

然后使用props中的数据getInitialState()来计算最大值,并在那里放置它的状态。似乎不需要等待组件安装。
wintvelt

1
异步数据呢?
slideshowp2'1

Answers:


98

这不是一个反模式调用setStatecomponentDidMount。实际上,ReactJS在其文档中提供了一个示例:

您应该在componentDidMount生命周期方法中使用AJAX调用填充数据。这样一来,您可以在检索数据时使用setState更新组件。

Doc中的示例

componentDidMount() {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.items
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

49
setState在这里一个回调函数完成-这是一个有点的不同场景
乔丹

1
我不确定这是反模式。在当前文档中提到在该环境中的状态componentDidMount将需要重新绘制,但没有它是坏的做法的提及。
worc'7

11
因此,为澄清遇到此问题的其他任何人,isMounted不建议使用生命周期函数,而将其用于设置组件状态被视为反模式。设置状态通过componentDidMount不被认为是反模式。
worc

1
只是想添加一个注释,以至于对此进行了Github讨论,如果您正在执行一些服务器端渲染或请求数据以调用componentDidMount中的setState,建议您这样做。然而,这通常是不推荐的原因是因为它可以触发一个双渲染(见eslint规则没有根本贴装设定状态
八月

1
@lux我在这里不记得具体细节,但我想我只是指出这里的机制有点不同-原始问题似乎不需要异步调用来设置所需的状态。我不是要表明您的代码无效:)
约旦

20

根据React文档,setState()componentDidMount()函数内调用完全可以。

这将导致render()被调用两次,这比仅调用一次效率低,但除此之外,它还可以。

您可以在这里找到文档:

https://reactjs.org/docs/react-component.html

以下是文档摘录:

您可以立即在componentDidMount()中调用setState()。它会触发额外的渲染,但是会在浏览器更新屏幕之前发生。这样可以保证即使在这种情况下render()将被调用两次,用户也不会看到中间状态。请谨慎使用此模式,因为它经常会导致性能问题...


1

linter抱怨使用setState({..})incomponentDidMount和的唯一原因componentDidUpdate是当组件渲染setState时立即导致组件重新渲染。但是要注意的最重要的一点是:在这些组件的生命周期内使用它并不是React中的反模式。

请看看这个问题。您将了解有关此主题的更多信息。感谢您阅读我的回答。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.