ReactJS - 在componentDidMount()和componentDidUpdate()中调用时,有效函数不起作用

时间:2018-04-19 22:15:19

标签: javascript reactjs adminlte

********编辑简化示例和澄清要求和问题**********

我很难接受这个,我希望有人可以提供帮助。

我有一个导航栏,我需要运行一个函数来将.active类添加到li元素中,如果它们有a.active的后代。

菜单系统是React组件: -

import React, {Component} from "react";
import { Link, NavLink } from 'react-router-dom'

import {activateMenu} from './ActivateMenu'

class SidebarMenu extends React.Component {

  componentDidMount() {
    activateMenu()
  }

  componentDidUpdate() {
    activateMenu()
  }

  render() {

    const renderNavLink = (to, text, icon, renderArrow = false) => {
      return(
        <NavLink to={to}>
          <i className="bullet">{icon}</i>
          <span>{text}</span>
          {renderArrow ? <span className="pull-right-container">
                <i className="angle-left"><FaAngleLeft /></i>
              </span> : null}
        </NavLink>
      )
    }

    return (
      <ul className="sidebar-menu" data-widget="tree">

        <li className="">
          {renderNavLink('/','Home',<FaHome />)}
        </li>

        <li className="treeview">
          {renderNavLink("#",'Users',<FaGroup />, true)}
          <ul className="treeview-menu">
            <li>
              {renderNavLink(userSearchSlug,'Search',<FaSearch />)}
            </li>
          </ul>
        </li>
        <button onClick={activateMenu}>Press Me</button>
      </ul>
    )
  }
}

export default SidebarMenu

这将给我一个像这样的HTML结构: -

<ul class="sidebar-menu tree" data-widget="tree">
  <li class="treeview">
    <a href="#">
      <i class="fa fa-dashboard"></i> <span>Links</span>
      <span class="pull-right-container">
            <i class="fa fa-angle-left pull-right"></i>
        </span>
    </a>
    <ul class="treeview-menu">
      <li>
        <a href="/link1"><i class="fa fa-circle-o"></i> Link1</a>
      </li>
      <li>
        <a href="/link2"><i class="fa fa-circle-o"></i> Link2</a>
      </li>
    </ul>
  </li>
</ul>

React渲染HTML后,我需要在.treeview&gt;上触发点击事件。如果在.treeview-menu下找到任何a.active节点,则为节点。所以: -

<li class="treeview">
    <a href="#" *****TRIGGER CLICK EVENT*****>
        <i class="fa fa-dashboard"></i> <span>Links</span>
        <span class="pull-right-container">
            <i class="fa fa-angle-left pull-right"></i>
        </span>
    </a>
    <ul class="treeview-menu">
        <li>
            <a href="/link1"><i class="fa fa-circle-o *****.ACTIVE CLASS HERE****"></i> Link1</a>
        </li>
        <li>
            <a href="/link2"><i class="fa fa-circle-o"></i> Link2</a>
        </li>
    </ul>
</li>

activeMenu()如下所示: -

$('ul.sidebar-menu li.treeview:not(.menu-open)').has('a.active').find('a').trigger( "click" );

当从onClick()从页面上的按钮调用时,此函数有效,但它在componentDidMount()和componentDidUpdate()中不起作用。该函数将运行(使用console.log()进行测试,但不会影响HTML。但是,如果我从Button运行它,它可以很好地工作。当HMR运行时,它也可以正常工作。

我不知道为什么会这样。有没有人有任何想法?

1 个答案:

答案 0 :(得分:2)

这可能正在发生,因为你直接选择元素而不是使用refs,虽然很难说因为我们不知道$('ul.sidebar-menu .treeview a').parent().has('a.active').parent().find('.treeview a')正在选择什么,这就是为什么这种代码是反模式的原因。

React可能处于某些状态,它不准备在这些点处理点击事件。尝试使用以下内容:

import React, {Component} from "react";
import { Link, NavLink } from 'react-router-dom'

class SidebarMenu extends React.Component {

  constructor(props) {
    super(props);
    this.menuRefs = [];
  }

  componentDidUpdate() {
    if (this.menuRefs.length) {
      this.menuRefs[0].click();
    }
  }

  render() {

    const renderNavLink = (to, text, icon, renderArrow = false) => {
      return(
        <NavLink to={to} innerRef={ref => this.menuRefs.push(ref)}>
          <i className="bullet">{icon}</i>
          <span>{text}</span>
          {renderArrow ? <span className="pull-right-container">
                <i className="angle-left"><FaAngleLeft /></i>
              </span> : null}
        </NavLink>
      )
    }

    return (
      <ul className="sidebar-menu" data-widget="tree">

        <li className="">
          {renderNavLink('/','Home',<FaHome />)}
        </li>

        <li className="treeview">
          {renderNavLink("#",'Users',<FaGroup />, true)}
          <ul className="treeview-menu">
            <li>
              {renderNavLink(userSearchSlug,'Search',<FaSearch />)}
            </li>
          </ul>
        </li>
        <button onClick={() => this.menuRefs[0] && this.menuRefs[0].click()}>Press Me</button>
      </ul>
    )
  }
}

export default SidebarMenu

注意

  1. 现在有一个“menuRefs”数组,你只需像普通的DOM元素一样使用它们。
  2. 我们推送到NavLink innerRef prop (found here)
  3. 中的menuRef

    但是请注意,您可能希望保留一张地图,以确保没有重复项被推送到menuRefs。

    要详细了解参考资料,请访问文档:https://reactjs.org/docs/refs-and-the-dom.html