javascript - React - setState() 在未安装的组件上

标签 javascript ajax reactjs state

在我的 React 组件中,当 ajax 请求正在进行时,我试图实现一个简单的微调器——我使用 state 来存储加载状态。

出于某种原因,我的 React 组件中的这段代码抛出了这个错误

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 undefined component.

如果我摆脱第一个 setState 调用,错误就会消失。

constructor(props) {
  super(props);
  this.loadSearches = this.loadSearches.bind(this);

  this.state = {
    loading: false
  }
}

loadSearches() {

  this.setState({
    loading: true,
    searches: []
  });

  console.log('Loading Searches..');

  $.ajax({
    url: this.props.source + '?projectId=' + this.props.projectId,
    dataType: 'json',
    crossDomain: true,
    success: function(data) {
      this.setState({
        loading: false
      });
    }.bind(this),
    error: function(xhr, status, err) {
      console.error(this.props.url, status, err.toString());
      this.setState({
        loading: false
      });
    }.bind(this)
  });
}

componentDidMount() {
  setInterval(this.loadSearches, this.props.pollInterval);
}

render() {

    let searches = this.state.searches || [];


    return (<div>
          <Table striped bordered condensed hover>
          <thead>
            <tr>
              <th>Name</th>
              <th>Submit Date</th>
              <th>Dataset &amp; Datatype</th>
              <th>Results</th>
              <th>Last Downloaded</th>
            </tr>
          </thead>
          {
          searches.map(function(search) {

                let createdDate = moment(search.createdDate, 'X').format("YYYY-MM-DD");
                let downloadedDate = moment(search.downloadedDate, 'X').format("YYYY-MM-DD");
                let records = 0;
                let status = search.status ? search.status.toLowerCase() : ''

                return (
                <tbody key={search.id}>
                  <tr>
                    <td>{search.name}</td>
                    <td>{createdDate}</td>
                    <td>{search.dataset}</td>
                    <td>{records}</td>
                    <td>{downloadedDate}</td>
                  </tr>
                </tbody>
              );
          }
          </Table >
          </div>
      );
  }

问题是为什么当组件应该已经安装时我会收到此错误(因为它是从 componentDidMount 调用的)我认为一旦安装组件就可以安全地设置状态?

最佳答案

没有看到渲染功能有点难。虽然已经可以发现您应该做的事情,但每次使用间隔时,您都必须在卸载时清除它。所以:

componentDidMount() {
    this.loadInterval = setInterval(this.loadSearches, this.props.pollInterval);
}

componentWillUnmount () {
    this.loadInterval && clearInterval(this.loadInterval);
    this.loadInterval = false;
}

由于卸载后可能仍会调用成功和错误回调,因此您可以使用间隔变量来检查它是否已挂载。

this.loadInterval && this.setState({
    loading: false
});

希望这有帮助,如果这不能完成工作,请提供渲染功能。

干杯

关于javascript - React - setState() 在未安装的组件上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32903001/

相关文章:

python - django-webpack-loader 不使用 react-app-rewired 渲染 React 应用程序

javascript - react 表在搜索排序上计算页面更改的页脚总和,我们如何实现这一点

javascript - React - 在返回 [object Object] 的 JSX markdown 中呈现链接

javascript - 打印网页没有任何提示?使用 javascript 或 jquery 或 vbscript

javascript - 用于将具有相同键和值的 React props 传递给组件的语法糖

javascript - 每次加载ajax或一次加载所有内容

javascript - 使用 JavaScript 查询 Sesame Triplestore

php - JavaScript 可以直接调用 PHP 函数,还是需要单独的 php 文件来调用函数?

javascript - 如何防止 htmlspecialchars (PHP) 将字符串中的整数转换

javascript - 简单的键/值数据库