【问题标题】:React - How to prevent click event from child componentReact - 如何防止来自子组件的点击事件
【发布时间】:2020-01-26 21:52:26
【问题描述】:

在标记为重复之前,它的不同之处。我有这种情况,我想将一些非预定义元素放入子组件中。当用户单击该元素时,它会在父元素事件上触发。单击子项时,如何停止父项上的事件触发器?让我用下面的例子来解释一下-

所以,它基本上是一个手风琴列表,通过单击每个项目的标题 div (list-container__item____title) 将显示正文 div (list-container__item____body)。

现在,在标题 div 中,我有一个链接 (list-container__item____title--link),它打开了一个覆盖(子组件)。覆盖内容来自 API 调用,它的包含是 HTML。我无法为该元素添加更多功能,因为我不知道其中包含什么,它基于用户选择。如果在 HTML 中有一些可点击的元素,如锚点、按钮等,则状态 (activeItem) 将更新为空 ('') 值。结果是相应的项目被折叠。有什么办法可以防止这种情况发生吗?

import React from 'react';

class DiamondFilters extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            activeItem: ''
        };
    }

    handleItemToggle = (name) => {
        if (this.state.activeItem === name) {
            this.setState({ activeItem: '' })
        } else {
            this.setState({ activeItem: name })
        }
    }

    render() {
        return (
            <div className="menu">
                <div className="list-container">
                    <div className={`list-container__item ${this.state.activeItem === "item1" ? 'active' : ''}`}>
                        <div className="list-container__item____title" onClick={() => this.handleItemToggle('item1')}>
                            <a className="list-container__item____title--link">Click Here 1</a>
                            <OverlayModal modalType="full" modalName="item1" />
                        </div>
                        <div className="list-container__item____body">
                            <p>There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.</p>
                        </div>
                    </div>
                    <div className={`list-container__item ${this.state.activeItem === "item2" ? 'active' : ''}`}>
                        <div className="list-container__item____title" onClick={() => this.handleItemToggle('item2')}>
                            <a className="list-container__item____title--link">Click Here 2</a>
                            <OverlayModal modalType="full" modalName="item2" />
                        </div>
                        <div className="list-container__item____body">
                            <p>There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.</p>
                        </div>
                    </div>
                </div>
            </div>
        );
    }

}

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

如果您需要使用带参数的回调来处理这些点击,您只需将事件添加为这些参数之一,然后将 Event.stopPropagation() 调用移动到回调中。

handleItemTitleLinkClick = (e, foo, bar) => {
    e.stopPropagation();
    // do stuff
}

...

<a className="list-container__item____title--link" onClick={e => handleItemTitleLinkClick(e, "whatever", "args")}>Click Here 1</a>

【讨论】:

  • 我可以在我的函数上做吗,因为我还必须传递一些参数
【解决方案2】:

您可以将 OverlayModal 包装在另一个组件(“Click Muncher”)中,以防止任何点击冒泡:

const ClickMuncher = ({ children }) => {
  return <div onClick={e => e.stopPropagation()}>{children}</div>;
};

并像这样使用它:

<div className="list-container__item____title" onClick={() => this.handleItemToggle('item1')}>
  <a className="list-container__item____title--link">Click Here 1</a>
  <ClickMuncher>
      <OverlayModal modalType="full" modalName="item1" />
  </ClickMuncher>
</div>

【讨论】:

  • 如果 有一些附加点击事件的内容,它会起作用吗?
  • 所以你想用一个附加了 stopPropagarltion 的 div 来包装覆盖模式内容?
  • 是的,它仍然可以工作。它可以防止点击冒泡,而不是点击处理。
  • 好的,谢谢。那么ClickMuncher需要在render()方法下定义吗?
  • 是的,围绕您需要捕获点击的任何元素或组件
【解决方案3】:

另一种可能的解决方案是将您的 OverlayModal 组件移到可折叠组件之外。这样,在模态框上进行的任何点击都不会调用与您的可折叠关联的点击处理程序。

  render() {
    return (
      <div className="menu">
        <div className="list-container">
          <div
            className={`list-container__item ${
              this.state.activeItem === "item1" ? "active" : ""
            }`}
          >
            <div
              className="list-container__item____title"
              onClick={() => this.handleItemToggle("item1")}
            >
              <a className="list-container__item____title--link">
                Click Here 1
              </a>
            </div>
            <div className="list-container__item____body">
              <p>
                There are many variations of passages of Lorem Ipsum available,
                but the majority have suffered alteration in some form, by
                injected humour, or randomised words which don't look even
                slightly believable.
              </p>
            </div>
          </div>
          <div
            className={`list-container__item ${
              this.state.activeItem === "item2" ? "active" : ""
            }`}
          >
            <div
              className="list-container__item____title"
              onClick={() => this.handleItemToggle("item2")}
            >
              <a className="list-container__item____title--link">
                Click Here 2
              </a>
            </div>
            <div className="list-container__item____body">
              <p>
                There are many variations of passages of Lorem Ipsum available,
                but the majority have suffered alteration in some form, by
                injected humour, or randomised words which don't look even
                slightly believable.
              </p>
            </div>
          </div>
          <OverlayModal modalType="full" modalName={this.state.activeItem} />
        </div>
      </div>
    );
  }

【讨论】:

    猜你喜欢
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 2020-09-09
    • 2018-07-08
    • 2012-01-17
    • 1970-01-01
    • 2015-04-28
    相关资源
    最近更新 更多