0

I'm trying to use a custom dropdown with a useState hook. I want to show the list when button is clicked but want to hide when user clicks anywhere outside the button. So, I'm having onClick events on parent div and button, but the onClick event of parent div triggers even when clicking the button, preventing the button to show the list. Here is the code:

import React, { useState } from "react";
    
export default function App() {
  const [showList, setShowList] = useState(false);
  return (
    <div className="" onClick={() => setShowList(false)}>
      <h1>Welcome Here</h1>
      <buton onClick={() => setShowList(true)}>Click here</buton>
      {showList && (
        <ul>
          <li>1</li>
          <li>2</li>
          <li>3</li>
        </ul>
      )}
    </div>
  );
}

And this is the codesandbox example: https://codesandbox.io/s/custom-dropdown-ycq90y?file=/src/App.js:0-426

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Fuaad
  • 197
  • 15

1 Answers1

1

You need to stop the propagation of the event:

<button
  onClick={(event) => {
    event.stopPropagation() // <--- this makes the event not bubble up the tree
    setShowList(true)
  }}
>
  Click here
</button>

This is not React specific, React is only wrapping the native behaviour for it's synthetic events.

Jakub Kotrs
  • 5,823
  • 1
  • 14
  • 30
  • 2
    Which is why there's at *least* one very well-established dupetarget for this: https://stackoverflow.com/questions/13682435/preventing-child-from-firing-parents-click-event – T.J. Crowder May 17 '23 at 08:14