admin管理员组

文章数量:1288031

Before mark as duplicate, Its differents. I have this scenario, where I suppose to get some non-predefined element into a child ponent. In where when the user clicks on that element it's fired on the parent element events. How can I stop the event trigger on the parent when the child is clicked? Let me explain more with the following example-

So, it's basically an accordion list, by clicking on each item title div (list-container__item____title) the body div (list-container__item____body) will display.

Now, inside the title div, I have a link (list-container__item____title--link) which opens an overlay (child ponent). The overlay content es from API call and the contains of it is HTML. I can't add some more functions for that element as I don't know what was included there, it's based on user choice. If in the HTML have some clickable element like an anchor, button, etc. the state (activeItem) is updated with empty ('') value. The result is the respective item is collapsed. Is there any way to prevent this event?

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>
        );
    }

}

Before mark as duplicate, Its differents. I have this scenario, where I suppose to get some non-predefined element into a child ponent. In where when the user clicks on that element it's fired on the parent element events. How can I stop the event trigger on the parent when the child is clicked? Let me explain more with the following example-

So, it's basically an accordion list, by clicking on each item title div (list-container__item____title) the body div (list-container__item____body) will display.

Now, inside the title div, I have a link (list-container__item____title--link) which opens an overlay (child ponent). The overlay content es from API call and the contains of it is HTML. I can't add some more functions for that element as I don't know what was included there, it's based on user choice. If in the HTML have some clickable element like an anchor, button, etc. the state (activeItem) is updated with empty ('') value. The result is the respective item is collapsed. Is there any way to prevent this event?

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>
        );
    }

}
Share Improve this question edited Sep 26, 2019 at 15:37 Daniel Smith asked Sep 26, 2019 at 15:10 Daniel SmithDaniel Smith 1,7344 gold badges30 silver badges64 bronze badges 4
  • Nope! It's not, the link you ment out, there was some predefine element attached with click event here is the different case. – Daniel Smith Commented Sep 26, 2019 at 15:20
  • event.stopPropagation() doesn't work? – nanobar Commented Sep 26, 2019 at 15:27
  • Possible duplicate of React prevent event bubbling in nested ponents on click – Joseph D. Commented Sep 26, 2019 at 15:34
  • Its not. Joseph – Daniel Smith Commented Sep 26, 2019 at 15:36
Add a ment  | 

3 Answers 3

Reset to default 8

You could wrap your OverlayModal in another ponent (a 'Click Muncher') that prevents any click bubbling:

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

And use it like this:

<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>

If you need to handle these clicks with a callback that takes parameters, you can just add the event as one of those params and move the Event.stopPropagation() call inside the callback.

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>

Another possible solution is to move your OverlayModal ponent outside of your collapsibles. That way any clicks made on the modal wouldn't invoke the click handler that's associated to your collapsible.

  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>
    );
  }

本文标签: javascriptReactHow to prevent click event from child componentStack Overflow