在componentDidMount()上设置状态

Nir*_*osh 52 reactjs

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

lux*_*lux 72

这不是一个反模式调用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
          });
        }
      )
  }
Run Code Online (Sandbox Code Playgroud)

  • `setState`在这里的回调函数中完成 - 这有点[不同场景](http://jaketrent.com/post/set-state-in-callbacks-in-react/) (33认同)
  • 所以,只是为了澄清任何绊倒这个问题和答案的人,生命周期函数`isMounted`已被弃用,并且使用它来设置组件状态被认为是反模式.通过`componentDidMount`设置状态不被视为反模式. (10认同)
  • 只是想添加一条评论,[Github 对此有讨论](https://github.com/airbnb/javascript/issues/684),如果您正在进行一些服务器端渲染或数据请求,建议您使用它在componentDidMount中调用setState。然而,通常不推荐这样做的原因是它会触发双重渲染(请参阅[eslint规则 no-did-mount-set-state](https://github.com/yannickcr/eslint-plugin-react/ blob/master/docs/rules/no-did-mount-set-state.md#prevent-usage-of-setstate-in-componentdidmount-reactno-did-mount-set-state) (2认同)

Lui*_*rez 8

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

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

您可以在这里找到文档:

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

以下是文档摘录:

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


Ham*_*mem 5

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

请看一下这个问题。您将对这个主题有更多了解。感谢您阅读我的回答。