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

我正在尝试模拟一种类似于在模式弹出窗口打开时单击叠加层的行为。在 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 工作的前提,它只是我想要模拟的行为的一个例子。


慕斯王
浏览 109回答 1
1回答

隔江千里

据我了解,您想从另一个组件修改 DOM 子树。为了实现您的目标,您可以使用ref.ref当您想直接访问HtmlElement API时,使用会很有帮助- 在我的示例中,我使用animate().&nbsp;请阅读文档,因为它描述了更多ref用例。下面是当用户点击时动画&nbsp;<Sidebar/>收缩的简单例子<Content />。const { useRef } = React;function Main() {&nbsp; const sidebar = useRef(null);&nbsp; const handleClick = () => {&nbsp; &nbsp; sidebar.current.hide();&nbsp; };&nbsp; return (&nbsp; &nbsp; <div className="main">&nbsp; &nbsp; &nbsp; <Sidebar ref={sidebar} />&nbsp; &nbsp; &nbsp; <Content onClick={handleClick} />&nbsp; &nbsp; </div>&nbsp; );}class Sidebar extends React.Component {&nbsp; constructor(props) {&nbsp; &nbsp; super(props);&nbsp; &nbsp; this.state = { visible: true };&nbsp; &nbsp; this.show = this.show.bind(this);&nbsp; &nbsp; this.sidebar = React.createRef(null);&nbsp; }&nbsp; show() {&nbsp; &nbsp; if (!this.state.visible) {&nbsp; &nbsp; &nbsp; this.sidebar.current.animate(&nbsp; &nbsp; &nbsp; &nbsp; { flex: [1, 2], "background-color": ["teal", "red"] },&nbsp; &nbsp; &nbsp; &nbsp; 300&nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; this.setState({ visible: true });&nbsp; &nbsp; }&nbsp; }&nbsp; hide() {&nbsp; &nbsp; if (this.state.visible) {&nbsp; &nbsp; &nbsp; this.sidebar.current.animate(&nbsp; &nbsp; &nbsp; &nbsp; { flex: [2, 1], "background-color": ["red", "teal"] },&nbsp; &nbsp; &nbsp; &nbsp; 300&nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; this.setState({ visible: false });&nbsp; &nbsp; }&nbsp; }&nbsp; render() {&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; <div&nbsp; &nbsp; &nbsp; &nbsp; ref={this.sidebar}&nbsp; &nbsp; &nbsp; &nbsp; className={this.state.visible ? "sidebar--visible" : "sidebar"}&nbsp; &nbsp; &nbsp; &nbsp; onClick={this.show}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; Sidebar&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; );&nbsp; }}function Content({ onClick }) {&nbsp; return (&nbsp; &nbsp; <div className="content" onClick={onClick}>&nbsp; &nbsp; &nbsp; Content&nbsp; &nbsp; </div>&nbsp; );}ReactDOM.render(<Main />, document.getElementById("root"));.main {&nbsp; display: flex;&nbsp; height: 100vh;}.sidebar {&nbsp; flex: 1;&nbsp; background-color: teal;}.sidebar--visible {&nbsp; flex: 2;&nbsp; background-color: red;}.content {&nbsp; flex: 7;&nbsp; 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>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript