从子组件通过回调触发setState()错误

时间:2018-09-25 12:04:02

标签: reactjs components state setstate reactstrap

从子组件触发回调时出现

setState()错误

组件第一次安装,先卸载然后再安装,按钮onclick => closeTab =>方法是setState不会改变状态吗?

**我无法共享完整代码,因为它不起作用,因为我使用服务器端组件生成器并将其注入eval()函数**

代码:

```没有jsx

class XPage extends React.PureComponent {
  constructor(props) {
    if (iwb.debugConstructor && iwb.debug) console.log("XPage.constructor", props);
    super(props);
    document.getElementById("id-breed").innerHTML = this.props.grid.name;
    iwb.killGlobalSearch();
    this.state = { activeTab: "x" };
    this.tabs = (iwb.tabs[this.props.grid.id])?[...iwb.tabs[this.props.grid.id]]:[{ name: "x", icon:"icon-list", title: "Liste", value: props.grid }];
    /**
     * @description
     * a Function to toggle between tabs
     * @param {Event} event - click event from tab
     */
    this.toggle = event => {
      var activeTab = event.target ? event.target.getAttribute("name") : event;
      if (this.state.activeTab !== activeTab) {
        var {
          tabs
        } = this;
        tabs &&
          tabs.forEach(tempTab => {
            if (tempTab.name === activeTab) {
              this.setState({
                activeTab
              });
              return true;
            }
          });
      }
      return false;
    };
    this.isActionInTabList = action => {
      var {
        tabs
      } = this;
      var stopToFetch = false;
      tabs &&
        tabs.forEach(tempTab => {
          if (tempTab.name === action) {
            this.toggle(action);
            stopToFetch = true;
          }
        });
      return stopToFetch;
    };
    /**
     * @description
     * A function responsible for opening tab getting component from the server and evaluating it on the page
     * @param {String} action - ['1-&toffer_id=4'] EditForm satrts 1-* , InsertForm satrts 2-*
     * @param {String} url - ['showForm?a=1&_fid=3988&twork_position_id=1']
     * @param {Object} params - a varible wich holds request body params
     * @param {Object} callAttributes - [{modal:false}] a variable used to pass params to a component which comes from the server
     */
    this.openTab = (action, url, params, callAttributes) => {
      if (this.state.activeTab !== action) {
        if (this.isActionInTabList(action)) return;
        fetch(url, {
            body: JSON.stringify(params || {}), // must match 'Content-Type' header
            cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
            credentials: "same-origin", // include, same-origin, *omit
            headers: {
              "content-type": "application/json"
            },
            method: "POST", // *GET, POST, PUT, DELETE, etc.
            mode: "cors", // no-cors, cors, *same-origin
            redirect: "follow", // *manual, follow, error
            referrer: "no-referrer" // *client, no-referrer
          })
          .then(
            response =>
            response.status === 200 || response.status === 0 ?
            response.text() :
            Promise.reject(
              new Error(response.text() || response.statusText)
            )
          )
          .then(
            result => {
              if (result) {
                var f;
                eval("f=(callAttributes, parentCt)=>{\n" + result + "\n}");
                var serverComponent = f(callAttributes || {}, this);
                if (serverComponent) {
                  if (callAttributes && callAttributes.modal) {
                    //console.log(callAttributes);
                    iwb.showModal({
                      body: serverComponent,
                      size: "lg",
                      title: serverComponent.props && serverComponent.props.cfg ?
                        serverComponent.props.cfg.name :
                        "",
                      color: "primary"
                    });
                  } else {
                    var plus = action.substr(0, 1) == "2";
                    if (this.isActionInTabList(action)) return;
                    this.tabs.push({
                      name: action,
                      icon: plus ? "icon-plus" : "icon-doc",
                      title: plus ? " Yeni" : " Düzenle",
                      value: serverComponent
                    });
                    this.setState({
                      activeTab: action
                    });
                  }
                }
              } else {
                toastr.error("Sonuc Gelmedi", " Error");
              }
            },
            error => {
              toastr.error(error, "Connection Error");
            }
          );
      }
    };
    iwb.openTab = this.openTab;
    /**
     * @description
     * A function responsible for closing tab and
     * delating CurrentTab from the state of Xpage Component
     * this function will be passed to whenever new tab is opened
     */
    this.closeTab = (event, forceRelaod = false) => {
      if (this.state.activeTab == "x") return;
      this.tabs = this.tabs && this.tabs.filter(tempTab => tempTab.name !== this.state.activeTab);
      if (forceRelaod) {
        this.tabs["0"].value.forceRelaod = Math.floor(Math.random() * 1000);
      }
// simply setState({activeTab:'x'}) =>this is not working as well but this.toggle("x")is working since i have tested by clicking tabs on UI 
      this.toggle("x");
    };
    /**
     * @description
     * A function is used to open new FormTab
     * @param {string} url
     */
    this.openForm = (url, callAttributes = {}) => {
      if (url) this.openTab("1-" + Math.random(), url, {}, callAttributes);
      return false;
    };
    iwb.openForm = this.openForm;
  }
  componentWillUnmount() {
    iwb.killGlobalSearch();
    iwb.pages[this.props.grid.id] = Object.assign({},this.state);
    iwb.tabs[this.props.grid.id] = [...this.tabs];
  }
  render() {
    if (iwb.debugRender) if (iwb.debug) console.log("XPage.render");
    return _(
      "div",
      {},
      _(
        Row,
        null,
        _(
          Col,
          { className: "mb-4" },
          _(
            Nav,
            { tabs: true, hidden: this.tabs.length == 1 },
            this.tabs.map(({ name, icon, title }, index) => {
              return _(
                NavItem,
                { key: "NavItem" + index },
                _(
                  NavLinkS,
                  {
                    className: classNames({
                      active: this.state.activeTab === name
                    }),
                    name,
                    onClick: event => this.toggle(event)
                  },
                  _("i", {
                    className: icon,
                    name,
                    title,
                    onClick: event => this.toggle(event)
                  }),
                  title && name != "x" && this.state.activeTab === name && title
                )
              );
            })
          ),
          _(
            TabContent,
            { activeTab: this.state.activeTab },
            this.tabs.map(({ name, value }, index) => {
              return _(
                TabPane,
                { key: "TabPane" + index, tabId: name },
                value.gridId
                  ? _(XMainGrid, {
                      openTab: this.openTab,
//#########sending event from the child####no need to bind since idecleared method in constructor
                      closeTab: (e,b)=>{ this.closeTab(e,b); },
                      ...value
                    })
                  : value
              );
            })
          )
        )
      )
    );
  }
}

``` **第二次安装组件时为setState。 **

**已测试:我已经测试了自己从ui(粘贴按钮)进行的切换,我已经在setState(bu debuugging)之前设置了状态,我已经使用状态clallback setSate({*},()=> {/这永远不会在第二个mount / console.log(this.state)})**

上运行

尝试于16.3.0 16.5.0

0 个答案:

没有答案