DEV Community

Cover image for How to stop child elements from inheriting parent element's onClick in React
Kunal Bagaria
Kunal Bagaria

Posted on • Edited on

How to stop child elements from inheriting parent element's onClick in React

So you created a div with an onClick that redirects to a link or does any normal function. But that div also contains child elements that would do different functions or nothing at all, and are still doing the parent element's function. There is a very simple solution to fix this.

Suppose this react code:

import React from 'react'

const NormalReactElement = () => {
   return (
      <div onClick={() => console.log('Parent Element!')}>
         <div id="child-element">
            <p>I am a child element</p>
         </div>
      </div>
   )
}
Enter fullscreen mode Exit fullscreen mode

So how do you fix this? Here's how you can fix this:

const NormalReactElement = () => {

   const handleChildElementClick = (e) => {
      e.stopPropagation()
      // Do other stuff here
   }

   return (
      <div onClick={() => console.log('Parent Element!')}>
         <div id="child-element" onClick={(e) => handleChildElementClick(e)}>
            <p>I am a child element</p>
         </div>
      </div>
   )
}
Enter fullscreen mode Exit fullscreen mode

Hope you like the quick solution to this, I'll see you in the next article.

Top comments (7)

Collapse
 
miketalbot profile image
Mike Talbot ⭐

I do this so much that I wrote this wrapper:

export function prevent(fn, defaultOnly) {
    return (e, ...params) => {
        e && e.preventDefault()
        !defaultOnly && e && e.stopPropagation()
        fn(e, ...params)
    }
}
Enter fullscreen mode Exit fullscreen mode

Then just:


import {prevent} from 'somewhere'

const NormalReactElement = () => {
   return (
      <div onClick={() => console.log('Parent Element!')}>
         <div id="child-element" onClick={prevent(()=>console.log("Child Element!"))>
            <p>I am a child element</p>
         </div>
      </div>
   )
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
realadamsmith profile image
Adam

Would this work if you need to pass another prop to 'prevent' function and you caant pass e?

Collapse
 
miketalbot profile image
Mike Talbot ⭐

It works for any number of properties to the event handler yes. The spread params take care of that. Events always have e as the first parameter, you'd need a rewrite if this wasn't a standard event I guess.

Thread Thread
 
realadamsmith profile image
Adam

I needed to pass a prop from a child element that wasnt (e), so I just remade the whole thing so the child wouldnt be dependednt on the parent element in the meantime

I gotta study this wrapper hmm

Collapse
 
kunal profile image
Kunal Bagaria • Edited

I see, I didn't think about it before. Thanks for sharing :)

Collapse
 
airtonix profile image
Zenobius Jiricek

This method will have you spending forever catching every single child click event.

Instead, use a ref, gate keep the clicking and discard clicks that aren't on the parent element:

stackoverflow.com/a/75562746/454615

Collapse
 
owenmelbz profile image
Owen Melbourne

in javascript*