【问题标题】:Simple React Component State, setState(...): Can only update a mounted or mounting componentSimple React Component State, setState(...): 只能更新一个挂载或挂载的组件
【发布时间】:2018-04-06 17:23:59
【问题描述】:

警告:setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了 setState()。这是无操作的。

我在 Stack Overflow 上阅读了很多这些解决方案,但仍然完全不知道为什么会发生这种情况以及如何解决这个问题。

我有我的图表组件,它呈现页面,组件已安装。当我将鼠标悬停在图表值 (onValueMouseOver) 上时,即出现错误。我只是不明白如果我能够将鼠标悬停在我的组件上,它是如何被视为未安装的。

我尝试创建一个单独的 this.mounted 变量,我将其设置为真/假,具体取决于 componentWillMountcomponentWillUnmount,并且仅在它们为真时使用 setState。下面的代码输出“挂载”消息(绝不是“卸载”消息),但它在启动时输出到控制台的值“真”,我假设因为我在构造函数中绑定了这些方法。但是当我将鼠标悬停时,会记录“假”。它没有记录错误,但仍然没有设置值,我需要它来做。

如果能指导我以“正确的方式”来处理这种情况,我们将不胜感激。我已经在几个地方使用了这种精确的方法,并且在我更新我的一些库和 webpack 配置之前它们都可以正常工作。

这是我的代码。我正在使用react-vis

class Chart extends Component {
  constructor(props) {
    super(props);
    this.mounted = false;
    this.state = {
      value: null
    };
    this.rememberValue = this.rememberValue.bind(this);
    this.forgetValue = this.forgetValue.bind(this);
  }

  componentWillMount() {
    console.log('mounting');
    this.mounted = true;
  }

  componentWillUnmount() {
    console.log('unmounting');
    this.mounted = false;
  }

  rememberValue(value) {
    console.log(this.mounted);
    if (this.mounted) {
      this.setState({value});
    }
  }

  forgetValue() {
    console.log(this.mounted);
    if (this.mounted) {
      this.setState({
        value: null
      });
    }
  }

  render() {
    const { series } = this.props;
    const { value } = this.state;
    return (
      <XYPlot />
        <LineMarkSeries
          data={series.data}
          onValueMouseOver={this.rememberValue}
          onValueMouseOut={this.forgetValue}
        />
        <XAxis />
        <YAxis />
        {value && <Hint value={value} {...this.props} />}
      </XYPlot>
    );
  }
}

【问题讨论】:

  • forgetValue 中的 if 条件是否应该是 !this.mounted?这是一个事件处理程序,当您将 this.mounted 设置为 false 时,它​​可以调用 setState
  • 糟糕。不,我的错字。更新中...
  • 尝试将您的componentWillMount 更改为componentDidMount 并从您的constructor 中删除您的this.mounted 分配。 componentWillMount 会产生意想不到的行为,实际上会在 React +17 中贬值
  • 这似乎对行为没有任何影响。 MouseOver 事件只会记录 this.mounted = undefined 的变化。

标签: javascript reactjs


【解决方案1】:

Omar 的解决方案是正确的,但某些 linter 可能会因为您在渲染函数中创建匿名函数而生气(出于性能原因)。您还有 2 个其他性能更高的选项。

forgetValue = () => {
}

constructor() {
  this.forgetValue = this.forgetValue.bind(this)
}

两者都只会创建一个将在组件的整个生命周期中使用的函数实例。在处理程序中创建一个函数每次重新渲染时都会创建一个新实例。

【讨论】:

  • 实际上这似乎奏效了。我将方法绑定到构造函数并执行箭头函数,但没有成功。我很好奇为什么使用方法绑定不起作用......这个解决方案也让我完全不必使用this.mounted
  • 使用其中一种。我认为当你同时尝试两者时,范围界定会变得不稳定
猜你喜欢
  • 2016-05-22
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 1970-01-01
相关资源
最近更新 更多