React - setState(...): 只能更新一个挂载或挂载的组件

Posted

技术标签:

【中文标题】React - setState(...): 只能更新一个挂载或挂载的组件【英文标题】:React - setState(...): Can only update a mounted or mounting component 【发布时间】:2017-08-12 01:51:45 【问题描述】:

在使用 react-router 的辅助组件内部时,我收到 setState 错误。任何人都可以在我的代码中看到任何问题吗?

import React,  Component  from 'react';
import  Row, Col  from 'react-bootstrap';
import  Card, CardTitle, CardText  from 'material-ui/Card';
import './App.css';

class Dashboard extends Component 
  constructor(props) 
    super(props);
    this.state = 
      info: []
    ;
    this.setInfo = this.setInfo.bind(this);

    this.setInfo();
  

  setInfo = () => 
    var info = [
      
        id: 0,
        title: 'Server Space',
        subtitle: '',
        textContent: ''
      ,
      
        id: 1,
        title: 'Pi Space',
        subtitle: '',
        textContent: ''
      
    ];
    this.setState( info: info );
  

  render() 
    return (
      <div>
        <h2>Info</h2>
        <Row>
          this.state.info.map((inf) => 
            return (
              <Col xs=12 md=4 key=inf.id>
                <Card className="card">
                  <CardTitle title=inf.title subtitle=inf.subtitle />
                  <CardText>inf.textContent</CardText>
                </Card>
              </Col>
            )
          )
        </Row>
      </div>
    )
  


export default Dashboard;

这会导致:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the Dashboard component.

有问题的线路是this.setState( info: info );

【问题讨论】:

【参考方案1】:

你不应该在构造函数中调用this.setState。 可以直接设置状态:

var info = [
  
    id: 0,
    title: 'Server Space',
    subtitle: '',
    textContent: ''
  ,
  
    id: 1,
    title: 'Pi Space',
    subtitle: '',
    textContent: ''
  
];

class Dashboard extends Component 
  constructor(props) 
    super(props);
    this.state = 
      info: info
    ;
    this.setInfo = this.setInfo.bind(this);
  

  setInfo = () => 
    this.setState( info: info );
  
  ...

【讨论】:

谢谢。我很困惑为什么这不能像以前那样工作,但我意识到我正在使用 superagent 并在异步结束函数中调用 setState 感谢分享,不适用于我的用例。这就是我所拥有的 constructor(props) super(props); this.state = data : this.props.cryptos, isLoading : false ; setInterval(() => this._query(query); , 6000); ; _handleResponse(response) this.setState( data : response, isLoading : false ); ; _query(query) this.setState( isLoading: true); fetch(query) .then(response => response.json()).then(json => this._handleResponse(json)) .catch(error => this.setState( isLoading: false, message: '错误:' + 错误 )); ; 我发现卸载组件时需要清除间隔,这是关于间隔的好文章reactnativequickly.com/book/chap07.html【参考方案2】:

组件constructor在组件被挂载之前被调用,所以你不能在其中调用setStatesetState只能在挂载的组件上调用)。构造函数是初始化状态的正确位置,但您应该直接设置状态:

constructor(props) 
  super(props);
  var info = [...];
  this.state= 
    info: info
  ;
 

请注意,在 constructor 之外,您永远不应该直接设置状态 - constructor 是您可以这样做的唯一例外。

【讨论】:

以上是关于React - setState(...): 只能更新一个挂载或挂载的组件的主要内容,如果未能解决你的问题,请参考以下文章

React setstate 只能更新挂载或挂载的组件——在重新渲染时

react常见问题

react setState

React的setState执行机制

react setstate触发render方法吗

react中this.setState的理解