简体   繁体   中英

How to prevent events from acting in nested divs when using React Hooks

I have nested div elements. Outside there should be events to move and to click. I want to enable a nested element to act as a button and to prevent the event from outside to act. In the example when we click on the red part, both events are happening. How can I stop the event from the green part when we click on the red part? stopPropagation() did not do the job. I am using React and my structure is more complex than in the example. But I wanted to reduce for reasons of clarity.

I would be happy if someone can help.

 #bigCircle { display: flex; justify-content: center; align-items: center; width: 180px; height: 180px; border-radius: 50%; background-color: green; } #smallCircle { width: 40px; height: 40px; border-radius: 50%; background-color: red; }
 <!DOCTYPE html> <html lang="en"> <head> </head> <body> <div id="bigCircle"> <div id="smallCircle"></div> </div> <script> document.getElementById("bigCircle").addEventListener("click",myBigCircle); document.getElementById("smallCircle").addEventListener("click",mySmallCircle); function myBigCircle(){ console.log("Hello");} function mySmallCircle(){ console.log("Bye");} </script> </body> </html>

I think it is related to React Hooks. Here you see the example with stopPropagation not working:

import React, { useState } from 'react';

function Test() {
    let [test, setTest] = useState(false);


    return (
        <div id="wrapper"
            style={styleBigCircle}
            onMouseUp={() => {
                setTest(false);
                console.log("Hello", test)
            }
            }>

            <div id="center"
                style={styleSmallCircle}
                onClick={(e) => {
                    e.stopPropagation();
                    setTest(!test);
                    console.log("Bye", test)
                }}
            >

            </div>

        </div>

    );
}

const styleBigCircle = {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    width: "180px",
    height: "180px",
    borderRadius: "50%",
    backgroundColor: "green"
}

const styleSmallCircle = {
    width: "40px",
    height: "40px",
    borderRadius: "50%",
    backgroundColor: "red"
}

export default Test;

I would be happy if someone knows how to fix this.

Use event.stopPropagation() to prevent parent trigger.

 #bigCircle { display: flex; justify-content: center; align-items: center; width: 180px; height: 180px; border-radius: 50%; background-color: green; } #smallCircle { width: 40px; height: 40px; border-radius: 50%; background-color: red; }
 <!DOCTYPE html> <html lang="en"> <head> </head> <body> <div id="bigCircle"> <div id="smallCircle"></div> </div> <script> document.getElementById("bigCircle").addEventListener("click",myBigCircle); document.getElementById("smallCircle").addEventListener("click",mySmallCircle); function myBigCircle(){ console.log("Hello");} function mySmallCircle(event){ event.stopPropagation() console.log("Bye"); } </script> </body> </html>

You are dealing with different events, so to prevent the child element from trigger the parent you would need to add the same event and stopPropagation() on that one instead:

<div
    id="center"
    style={styleSmallCircle}
    onMouseUp={e => {
      e.stopPropagation();
    }}
    onClick={e => {
      setTest(!test);
      console.log("Bye");
    }}
/>

Here is a fully working example:

 const Test = () => { let [test, setTest] = React.useState(false); return ( <div id="wrapper" style={styleBigCircle} onMouseUp={() => { console.log("Hello"); }} > <div id="center" style={styleSmallCircle} onMouseUp={e => { e.stopPropagation(); }} onClick={e => { console.log("Bye"); }} /> </div> ); }; const styleBigCircle = { display: "flex", justifyContent: "center", alignItems: "center", width: "180px", height: "180px", borderRadius: "50%", backgroundColor: "green" }; const styleSmallCircle = { width: "40px", height: "40px", borderRadius: "50%", backgroundColor: "red" }; const rootElement = document.getElementById("root"); ReactDOM.render(<Test />, rootElement);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM