【问题标题】:Maximum call stack size exceeded;超出最大调用堆栈大小;
【发布时间】:2017-12-27 00:02:15
【问题描述】:

我遇到了问题,当我使用componentDidMount()componentDidMount() 使用功能时显示工具提示_getContentTooltip() 然后问题显示错误common.js:444 RangeError: Maximum call stack size exceeded

import ZCommon from 'utils/common';
import React from 'react';
import ReactDOM from 'react-dom';

class TooltipUtil extends React.Component {
  constructor(props) {
        super(props);
        this.state = {
      guidesContent: [],
      zguides: [],
            current: 1,
      hidden: 0
        };
    }
  shouldComponentUpdate(nextProps, nextState) {
    return (
      this.state.current !== nextState.current ||
      this.state.zguides !== nextState.zguides
    );
  }
  _storageData() {
        this.state.guidesContent = [{
                "id":"1",
          "description": "Đây là title của người chat or group",
                "name":"tabmsg.searchicon",
          "title": "abc",
            }, {
                        "id":"2",
                        "name":"tabmsg.creategroup",
                "description": "Bạn click vào đây để tạo nhóm",
                 "title": "Xưu nhân",
            }, {
                        "id":"3",
                        "name":"csc.header.search",
                "description": "Đây là khung để nhập nội dung chat",
                 "title": "abc",

                                            }];
      this.setState({
        guidesContent: this.state.guidesContent.sort(function(a,b){ return a.id > b.id } )
      });
      return this.state.guidesContent;
  }
  _getContentTooltip(){
    // this.serverRequest.abort();
    let current= this.state.current;
    let _guides = this._storageData();
    let ele = document.querySelectorAll(".tooltip");
    for (var i = 0; i < ele.length; i++) {
        var no = ele[i].getAttribute('data-tooltip');
      let Tcontent = Object.keys(_guides).filter(function(key) {
                if(_guides[key].name == no){
          if(_guides[key].id == current){
            return key;
          }
                }
            });
      this.setState({
        zguides: this.state.guidesContent[Tcontent]
      })
    }
  }
  componentDidMount(){
    this._getContentTooltip();
  }
  componentDidUpdate(){
    this.componentDidMount();
  }
  _handlerClickClose() {
      let _guides = this._storageData();
      if(this.state.current <= _guides.length ){
          this.setState({
            current: this.state.current + 1
          });
      }
  }
  render() {
    let guides = null;
    let obj = this.state.zguides;
    let show = this.state.zguides != undefined ? "show" : ' ';
    console.log(this.state.zguides);
      guides = (
        <div className={'guide ' + show } style={{ width:'200px',left:'0'}}>
          <div className="guide-content flx">
              <div href="#" className="fa fa-close" onClick= {this._handlerClickClose.bind(this)}></div>
              <h4>{this.state.zguides['title']}</h4>
              <p>{this.state.zguides['description']}</p>
          </div>
        </div>
      );
    return guides;
    }
  _handlerClickClose() {
      let _guides = this._storageData();
      if(this.state.current <= _guides.length ){
          this.setState({
            current: this.state.current + 1
          });
      }
  }
}
export default TooltipUtil;

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    _getContentTooltip() 函数中,您正在更改状态。这会导致组件更新,因此 componentDidUpdate() 函数运行,它还会再次调用 componentDidMount( )。该函数再次调用 getContentTooltip()。所以注释下面的行

    componentDidUpdate(){ //this.componentDidMount(); }

    【讨论】:

      【解决方案2】:

      首先,您不应该强制生命周期函数强制调用。现在会发生最大堆栈大小错误,因为_getContentTooltip 正在设置状态,因此将触发重新渲染,导致调用 componentDidUpdate 生命周期函数,您再次调用 componentDidMount 从而进入无限循环。您可能会说您已经检查过 shouldComponentUpdate 中的先前状态值和当前状态值是否相等,但是比较像 this.state.zguides !== nextState.zguides 这样的数组将返回 true。

      看到这个答案:

      How to compare arrays in JavaScript?

      如果要周期性触发_getContentTooltip,在componentDidMount的setInterval函数中调用

      class TooltipUtil extends React.Component {
        constructor(props) {
              super(props);
              this.state = {
            guidesContent: [],
            zguides: [],
                  current: 1,
            hidden: 0
              };
          }
        shouldComponentUpdate(nextProps, nextState) {
          return (
            this.state.current !== nextState.current ||
            !this.state.zguides.equals(nextState.zguides)
          );
        }
        _storageData() {
              this.state.guidesContent = [{
                      "id":"1",
                "description": "Đây là title của người chat or group",
                      "name":"tabmsg.searchicon",
                "title": "abc",
                  }, {
                              "id":"2",
                              "name":"tabmsg.creategroup",
                      "description": "Bạn click vào đây để tạo nhóm",
                       "title": "Xưu nhân",
                  }, {
                              "id":"3",
                              "name":"csc.header.search",
                      "description": "Đây là khung để nhập nội dung chat",
                       "title": "abc",
      
                                                  }];
            this.setState({
              guidesContent: this.state.guidesContent.sort(function(a,b){ return a.id > b.id } )
            });
            return this.state.guidesContent;
        }
        _getContentTooltip(){
          // this.serverRequest.abort();
          let current= this.state.current;
          let _guides = this._storageData();
          let ele = document.querySelectorAll(".tooltip");
          for (var i = 0; i < ele.length; i++) {
              var no = ele[i].getAttribute('data-tooltip');
            let Tcontent = Object.keys(_guides).filter(function(key) {
                      if(_guides[key].name == no){
                if(_guides[key].id == current){
                  return key;
                }
                      }
                  });
            this.setState({
              zguides: this.state.guidesContent[Tcontent]
            })
          }
        }
        componentDidMount(){
          setInterval(() => {
            this._getContentTooltip();
          }, 1000)
        }
        _handlerClickClose() {
            let _guides = this._storageData();
            if(this.state.current <= _guides.length ){
                this.setState({
                  current: this.state.current + 1
                });
            }
        }
        render() {
          let guides = null;
          let obj = this.state.zguides;
          let show = this.state.zguides != undefined ? "show" : ' ';
          console.log(this.state.zguides);
            guides = (
              <div className={'guide ' + show } style={{ width:'200px',left:'0'}}>
                <div className="guide-content flx">
                    <div href="#" className="fa fa-close" onClick= {this._handlerClickClose.bind(this)}></div>
                    <h4>{this.state.zguides['title']}</h4>
                    <p>{this.state.zguides['description']}</p>
                </div>
              </div>
            );
          return guides;
          }
        _handlerClickClose() {
            let _guides = this._storageData();
            if(this.state.current <= _guides.length ){
                this.setState({
                  current: this.state.current + 1
                });
            }
        }
      }
      export default TooltipUtil;
      

      【讨论】:

      • 我为你使用了代码,所以如果我评论 //this.componentDidMount(); 会显示错误和警告 Warning: performUpdateIfNecessary: Unexpected batch number (current 99, pending 6)this.state.zguides.equal is not a function单击关闭和当前更新时,工具提示不会获取下一个内容
      • 我在我的答案检查中提供了一个比较数组的链接,我的代码中有错字
      猜你喜欢
      • 1970-01-01
      • 2015-10-24
      • 2015-12-29
      • 2020-12-06
      • 2018-02-06
      • 2020-06-28
      • 2016-02-28
      • 2019-05-21
      • 2019-05-29
      相关资源
      最近更新 更多