为了账号安全,请及时绑定邮箱和手机立即绑定

单击给定组件外部时,如何从 React.JS 组件内的元素中删除类?

单击给定组件外部时,如何从 React.JS 组件内的元素中删除类?

慕斯王 2022-12-22 12:41:14
我正在尝试模拟一种类似于在模式弹出窗口打开时单击叠加层的行为。在 sidenav 组件外部单击时,我想关闭当前处于某个flyout模式的所有元素。我有一个多层嵌套导航菜单,存储在它自己的组件中,Sidebar. 我有以下代码处理clicks发生在Sidebar组件外部的代码:class Sidebar extends React.Component {    ...    handleClick = (e) => {      if (this.node.contains(e.target)) {        return;      }        console.log('outside');    };      componentDidMount() {      window.addEventListener('mousedown', this.handleClick, false);    }    componentWillUnmount() {      window.removeEventListener('mousedown', this.handleClick, false);    }    render() {      return (          <div              ref={node => this.node = node}              className="sidebar"              data-color={this.props.bgColor}              data-active-color={this.props.activeColor}          >          {renderSideBar()}          </div>      );    }    ...}这部分工作正常 - 但是当弹出菜单在单击父菜单选项时显示时,我希望它关闭当前打开的任何弹出菜单。-| | - Menu Item 1  |  |-option 1 (currently open)  |-option 2 - Menu Item 2  |   |-option 1 (closed)  |-option 2 (closed, clicked to expand - this is when it should close [Menu Item 1/Option 1]<li>在映射包含菜单结构的数据对象时,使用标签生成菜单项。有没有一种方法可以基本上选择所有具有 'collapse' / aria-expanded="true" 类的注册对象并将其删除?类似于如何jQuery选择 dom 元素并操作它们。我知道这不是 React 工作的前提,它只是我想要模拟的行为的一个例子。
查看完整描述

1 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

据我了解,您想从另一个组件修改 DOM 子树。为了实现您的目标,您可以使用ref.

ref当您想直接访问HtmlElement API时,使用会很有帮助- 在我的示例中,我使用animate(). 请阅读文档,因为它描述了更多ref用例。

下面是当用户点击时动画 <Sidebar/>收缩的简单例子<Content />

const { useRef } = React;


function Main() {

  const sidebar = useRef(null);


  const handleClick = () => {

    sidebar.current.hide();

  };


  return (

    <div className="main">

      <Sidebar ref={sidebar} />

      <Content onClick={handleClick} />

    </div>

  );

}


class Sidebar extends React.Component {

  constructor(props) {

    super(props);

    this.state = { visible: true };

    this.show = this.show.bind(this);

    this.sidebar = React.createRef(null);

  }


  show() {

    if (!this.state.visible) {

      this.sidebar.current.animate(

        { flex: [1, 2], "background-color": ["teal", "red"] },

        300

      );

      this.setState({ visible: true });

    }

  }


  hide() {

    if (this.state.visible) {

      this.sidebar.current.animate(

        { flex: [2, 1], "background-color": ["red", "teal"] },

        300

      );

      this.setState({ visible: false });

    }

  }


  render() {

    return (

      <div

        ref={this.sidebar}

        className={this.state.visible ? "sidebar--visible" : "sidebar"}

        onClick={this.show}

      >

        Sidebar

      </div>

    );

  }

}


function Content({ onClick }) {

  return (

    <div className="content" onClick={onClick}>

      Content

    </div>

  );

}


ReactDOM.render(<Main />, document.getElementById("root"));

.main {

  display: flex;

  height: 100vh;

}


.sidebar {

  flex: 1;

  background-color: teal;

}


.sidebar--visible {

  flex: 2;

  background-color: red;

}


.content {

  flex: 7;

  background-color: beige;

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="root"></div>


查看完整回答
反对 回复 2022-12-22
  • 1 回答
  • 0 关注
  • 48 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信