首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >警告react : setState(...):只能更新已安装或正在安装的组件

警告react : setState(...):只能更新已安装或正在安装的组件
EN

Stack Overflow用户
提问于 2019-03-25 22:45:50
回答 2查看 50关注 0票数 0

警告: setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未挂载的组件上调用setState()。这是个禁区。

这是一个react应用程序,横幅固定在屏幕上并传递随机图像。它的编写方式是生成有问题的警告。

代码语言:javascript
复制
import React from "react";
import Lightbox from "react-image-lightbox";
import logo from "./logo.png";

class Banner extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      images: [],
      currentImage: logo,
      isOpen: false,
      sidebarOpen: true
    };
  }

  async componentWillMount() {
    await this.getBanners();
    this.setState({ currentImage: this.state.images[0].url });

    setInterval(async () => {
      await this.getBanners();
    }, 300000);

    let i = 0;
    setInterval(
      () => {
        this.setState({ currentImage: this.state.images[i].url });
        if (i >= this.state.images.length - 1) {
          i = 0;
        } else {
          i++;
        }
      },
      10000,
      i
    );
  }

  async getBanners() {
    const data = await (await fetch("/api/banners/active")).json();
    if (data.true) {
      this.setState({ images: data.true });
    }
  }

  render() {
    const { isOpen } = this.state;

    return (
      <div>
        {isOpen && (
          <Lightbox
            mainSrc={this.state.currentImage}
            onCloseRequest={() => this.setState({ isOpen: false })}
          />
        )}
        <footer>
          <a>
            <img
              width={270}
              height="200"
              src={this.state.currentImage}
              onClick={() => this.setState({ isOpen: true })}
              alt="idk"
            />
          </a>
        </footer>
      </div>
    );
  }
}

export default Banner;

有人能帮助改进这段代码吗?

EN

回答 2

Stack Overflow用户

发布于 2019-03-25 22:49:12

您可以将从setInterval返回的数字放在您的实例上,并在componentWillUnmount中使用clearInterval停止间隔,这样在卸载组件后,它们就不会继续运行。

代码语言:javascript
复制
class Banner extends React.Component {
  constructor(props) {
    super(props);

    this.bannerInterval = null;
    this.currentImageInterval = null;
    this.state = {
      images: [],
      currentImage: logo,
      isOpen: false,
      sidebarOpen: true
    };
  }

  async componentDidMount() {
    await this.getBanners();
    this.setState({ currentImage: this.state.images[0].url });

    this.bannerInterval = setInterval(async () => {
      await this.getBanners();
    }, 300000);

    let i = 0;
    this.currentImageInterval = setInterval(
      () => {
        this.setState({ currentImage: this.state.images[i].url });
        if (i >= this.state.images.length - 1) {
          i = 0;
        } else {
          i++;
        }
      },
      10000,
      i
    );
  }

  componentWillUnmount() {
    clearInterval(this.bannerInterval);
    clearInterval(this.currentImageInterval);
  }

  // ...
}
票数 1
EN

Stack Overflow用户

发布于 2019-03-25 22:47:54

将此模板用于具有以下状态的任何基于类的组件:

忘记了setState(),使用setComponentState声明下来:

代码语言:javascript
复制
class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      // other fields...
      isUnmounted: false,
    };
  }

  componentWillUnmount() {
    this.setState({ isUnmounted: true });
  }

  setComponentState = (values) => {
    if (!this.state.isUnmounted) this.setState(values);
  };
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55340431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档