【问题标题】:React warning setState(...): Can only update a mounted or mounting componentReact 警告 setState(...):只能更新已安装或正在安装的组件
【发布时间】:2016-09-20 11:50:39
【问题描述】:

我在控制台中收到此错误/警告:

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

编辑安装组件

这里是我安装组件的地方:

componentDidMount()
    {
        if (this.isVisible()) {
            this.setState({visible: true});
        }

        this.bindEventListeners();
    }

这是导致问题的代码:

bindEventListeners()
    {
        let visibilityEvent = function (event) {
            event.currentTarget.removeEventListener(event.type, visibilityEvent);
            // protect the component against unloading
            if (this.isVisible()) {
                this.setState({visible: true});
            }

            // no need to call the timeout when its already visible
            if (!this.state.visible) {
                let scrollEvnt = setTimeout(function () {
                    EventContainer.readWindowEvent('scroll', visibilityEvent);
                }, 100);

                this.setState({scrollEv: scrollEvnt});
            }

        }.bind(this);

        EventContainer.readWindowEvent('scroll', visibilityEvent);
    }

更准确地说,这一行:

this.setState({scrollEv: scrollEvnt});

如果我理解正确,这意味着我需要一种方法来卸载滚动事件。但我不确定这是否可能。我很确定你不能在(vanilla)javascript/React 中取消绑定滚动事件。

编辑2 isVisible函数

isVisible()
    {
        let isVisible = true;

        try {
            let heightElement = ReactDOM.findDOMNode(this).getBoundingClientRect().top;

            isVisible = heightElement - window.innerHeight < 0;
        } catch (error) {
            console.warn('Falling back');
        }

        return isVisible;
    }

我可能错了,但我不确定如何解决此警告/错误。也许有人可以帮助我?任何帮助表示赞赏:)

非常感谢!

【问题讨论】:

  • 该错误表示您在组件挂载之前调用了setState函数。
  • @AsafDavid 感谢您的回复,但我不确定如何解决。我添加了我的 componentDidMount 函数,如果需要,可以查看已编辑的 OP :)
  • 你可能需要处理 componentWillUnmount 并移除那里的事件监听器
  • @Tom 感谢您的回答!我知道这一点,但我不确定是否可以删除滚动事件侦听器
  • 你可以移除一个滚动事件监听器,是的

标签: javascript reactjs


【解决方案1】:

我认为我们可能需要查看更多代码才能弄清楚这一点。

几个问题:

  • 您确定不是从其他地方调用 bindEventListeners() 吗?
  • 为什么在拥有 this.isVisible() 时还需要“this.state.visible”?

This diagram has helped me a lot in keeping track of where everything happens in a react object's lifecycle

【讨论】:

  • 是的,我确定我没有从其他地方调用 bindEventListeners :) 并且“this.state.visible”检查状态是否已经可见:false 不是代码上方的注释 // no need to call the timeout when its already visible我'将使用 isVisible 函数更新 OP
  • 有道理——我最近遇到了一个类似的错误,它似乎是通过确保 setState 只为componentDidMount() 中的属性(及其调用的函数)调用一次来解决的。我想知道是否真的有必要将这段代码写两次:if (this.isVisible()) { this.setState({visible: true}); }componentDidMount()bindEventListeners()
  • 是的,因为在 componentDidMount 中它显然将其设置为 true,并且在 bindEventListeners 中它确保组件自行卸载。我希望你明白我想说什么:)
【解决方案2】:

你需要移除componentWillUnmount中的滚动事件监听器

以下内容应该可行:

constructor(props) {
    super(props);
    this.onScroll = this.onScroll.bind(this);
}

componentDidMount()
{
    window.addEventListener('scroll', this.onScroll);
}

componentWillUnmount()
{
    window.removeEventListener('scroll', this.onScroll);
}

onScroll(event)
{
    //handle event here
}

【讨论】:

    猜你喜欢
    • 2016-10-13
    • 2017-03-02
    • 2017-04-26
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    • 2018-03-26
    相关资源
    最近更新 更多