Reputation: 57
I'm trying to check if anything but the ordered list and it's children have been clicked here
function Heeeeelp😭() {
function checkClick(e) {
if (!e.target == first-list || children) { //looking for something like this
//do something
}
}
return (
<div onClick={e => {checkClick(e)}} className="container">
<ol className="first-list">
<li></li>
<li></li>
<li></li>
</ol>
<ul className="second-list">
<li></li>
<li></li>
<li></li>
</ul>
</div>
)}
Upvotes: 0
Views: 718
Reputation: 22474
You can use something like this if (e.target.closest('.second-list')) {..}
, this statement, here is a complete example
const { useState } = React;
function Comp() {
const [ clicked, setClicked ] = useState('NONE');
function checkClick(e) {
if (e.target.closest('.first-list')) {
setClicked('first list');
}
if (e.target.closest('.second-list')) {
setClicked('second list');
}
}
return (
<div onClick={e => {checkClick(e)}} className="container">
<ol className="first-list">
<li>first</li>
<li>second</li>
<li>third</li>
</ol>
<ul className="second-list">
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
<div>Clicked List <strong>{ clicked }</strong></div>
</div>
)}
ReactDOM.render(
<Comp/>,
document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
Upvotes: 3
Reputation: 162
I've used this pattern a bunch and it does the trick (assuming you can use hooks). An equivalent pattern could be made without hooks if needed.
import { useRef, useEffect } from "react";
export default function App() {
const listRef = useRef(null);
const handleClickOutside = (e) => {
if (listRef.current && !listRef.current.contains(e.target)) {
console.log("Clicked somewhere besides the list.");
}
};
useEffect(() => {
document.addEventListener("mousedown", handleClickOutside, true);
return () => {
document.removeEventListener("mousedown", handleClickOutside, true);
};
}, []);
return (
<div>
<ol ref={listRef}>
<li>List 0 Item 0</li>
<li>List 0 Item 1</li>
<li>List 0 Item 2</li>
</ol>
<ul>
<li>List 1 Item 0</li>
<li>List 1 Item 1</li>
<li>List 1 Item 2</li>
</ul>
</div>
);
}
Upvotes: 2
Reputation: 1407
You can write 2 separate functions, one for each list and pass them directly to the lists instead of trying to handle everything from the container.
That way, clicking on any child of a list will trigger the correct desired behavior
const Component = () => {
const handleClickFirstList = () => {
// do something
}
const handleClickSecondList = () => {
// do something else
}
return (
<div className="container">
<ol className="first-list" onClick={handleClickFirstList}>
<li></li>
<li></li>
<li></li>
</ol>
<ul className="second-list" onClick={handleClickSecondList}>
<li></li>
<li></li>
<li></li>
</ul>
</div>
)}
Upvotes: 1