【问题标题】:Can't call setState on a Component that is not yet mounted - tsx无法在尚未安装的组件上调用 setState - tsx
【发布时间】:2019-03-18 09:46:21
【问题描述】:

我找到了一些关于这个问题的帖子,但没有一个能解决我的问题。

无法在尚未安装的组件上调用 setState。这是一个无操作,但它可能表明您的应用程序中存在错误。

Can't call setState on a component that is not yet mounted

React app. Can't call setState on a component that is not yet mounted

import React, { Component } from 'react';
import { Card, CardHeader, CardBody, Button, Collapse } from 'reactstrap';

class MyComponent extends React.Component<any, any> {
  constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    this.state = {
      collapse: false,
    };
  }

  toggle() {
    this.setState({ collapse: !this.state.collapse });
  }

  render() {
    return (
          <Card>
            <CardHeader>
              <Button color="link" onClick={this.toggle} className="float-right">
                Click me to toggle collapse
              </Button>
            </CardHeader>
            <Collapse isOpen={this.state.collapse}>
              <CardBody>
                The content being collapsed
              </CardBody>
            </Collapse>
          </Card>
    );
  }
}

export default MyComponent;
  • 如果我输入componentDidMount() { console.log("Mounted!"); },那么它仍然会出现在控制台窗口中。
  • 我尝试过类似线程的答案,例如 install babel polyfill、delete react-hot-loader,但它们都不起作用。
  • 我在每个组件中都遇到了这个问题,我有 setState 和一个按钮(或类似的东西)来调用该方法。
  • 有人有解决办法吗?我很感激他们每一个人。 非常感谢

【问题讨论】:

  • 请用minimal reproducible example 更新您的问题,证明问题,最好是可运行 使用堆栈片段([&lt;&gt;] 工具栏按钮)。 Stack Snippets 支持 React,包括 JSX; here's how to do one。您使用了 Stack Snippets,但没有使其可运行(单击“运行代码 sn-p”失败,因为它缺少库、使用导出、具有 TypeScript 类型注释等)。
  • 这不是问题,但这是错误的:this.setState({ collapse: !this.state.collapse }); 当您根据现有状态设置状态时,您必须使用回调版本:this.setState(({collapse}) =&gt; ({collapse: !collapse })); 更多:reactjs.org/docs/…(但同样,这不是问题,症状会有所不同。)
  • 您应该像这样绑定 onClick 事件:onClick={this.toggle.bind(this)} 并删除构造函数上的 this.toggle
  • @jgoday - 不,在构造函数中这样做不仅没问题,而且效率更高,而且是一个标准的习惯用法。
  • @T.J.Crowder 对不起,你完全正确。错误一定在另一件事上。最小样本 (jsfiddle.net/7a6drL35/1) 工作正常。

标签: javascript reactjs typescript react-tsx


【解决方案1】:

不知何故,当我构建生产时,问题就解决了

.\mvnw -Pprod -DskipTests

。非常感谢那些花时间帮助我的人。

【讨论】:

  • 这是一件坏事:不要跳过测试来构建生产。您应该尝试解决您的问题。
【解决方案2】:

您收到此错误是因为您尝试更改未安装组件的状态。如果在组件从其父组件中卸载后触发回调,则会发生这种情况。

您可以跟踪组件的挂载状态如下:

import React, { Component } from 'react';
import { Card, CardHeader, CardBody, Button, Collapse } from 'reactstrap';

class MyComponent extends React.Component<any, any> {
  mounted = false;

  constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    this.state = {
      collapse: false,
    };
  }

  componentWillMount() { this.mounted = true; }
  componentWillUnmount() { this.mounted = false; }

  toggle() {
    if(this.mounted) {
       this.setState(({collapse}) => ({ collapse: !collapse }));
    }
  }

  render() {
    return (
          <Card>
            <CardHeader>
              <Button color="link" onClick={this.toggle} className="float-right">
                Click me to toggle collapse
              </Button>
            </CardHeader>
            <Collapse isOpen={this.state.collapse}>
              <CardBody>
                The content being collapsed
              </CardBody>
            </Collapse>
          </Card>
    );
  }
}

export default MyComponent;

【讨论】:

  • 这并不能解决问题 xD 现在 "someAction()" 不会做任何事情 :( 谢谢你的回答。
  • 当然,这只是一个你需要适应的样本。这是完整的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 2021-07-21
  • 1970-01-01
相关资源
最近更新 更多