Mastering Event Delegation in JavaScript and React (Beginner to Advanced

krishankrishan
4 min read

Event delegation is a powerful concept in JavaScript and React that helps you write efficient, scalable, and cleaner code. This guide walks you through it in two simple steps, from beginner to advanced, with real-world examples and interview-ready questions.


πŸ”Ή Step 1: Understanding Event Delegation (Beginner)

βœ… What is Event Delegation?

Event delegation is a technique where you attach a single event listener to a parent element, and let events from child elements bubble up to it. You can then handle all those events from one place.

πŸ“¦ Why is it useful?

  • Improves performance βœ…

  • Reduces number of event listeners βœ…

  • Works great with dynamic elements βœ…

🧠 Basic JavaScript Example:

<ul id="menu">
  <li>Home</li>
  <li>About</li>
  <li>Contact</li>
</ul>
document.getElementById("menu").addEventListener("click", function (e) {
  if (e.target.tagName === "LI") {
    alert("You clicked: " + e.target.textContent);
  }
});

No matter how many <li> items are added dynamically, this listener still works!

🧠 React Example:

const List = ({ items }) => {
  const handleClick = (e) => {
    const li = e.target.closest("li");
    if (li) {
      alert("Clicked: " + li.textContent);
    }
  };

  return (
    <ul onClick={handleClick}>
      {items.map((item, i) => (
        <li key={i}>{item}</li>
      ))}
    </ul>
  );
};

πŸ§ͺ Common Use Cases

  • Dropdown menus

  • Modals

  • Forms with dynamically added fields

  • Chat messages / notifications


πŸ”Ή Step 2: Advanced Usage, Pitfalls & Best Practices

🧩 Preventing Event Bubbling

Use event.stopPropagation() to prevent bubbling:

child.addEventListener("click", (e) => {
  e.stopPropagation();
});

In React:

const handleClick = (e) => {
  e.stopPropagation();
};

⚠️ stopPropagation() vs stopImmediatePropagation()

  • stopPropagation() β†’ Stops going up the DOM

  • stopImmediatePropagation() β†’ Stops all other handlers too

πŸ”„ Dynamic UI with Dropdown Example in React:

const Dropdown = () => {
  const dropdownRef = useRef();
  const [open, setOpen] = useState(false);

  const toggle = (e) => {
    e.stopPropagation();
    setOpen(!open);
  };

  const handleClickOutside = (e) => {
    if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
      setOpen(false);
    }
  };

  useEffect(() => {
    document.addEventListener("click", handleClickOutside);
    return () => document.removeEventListener("click", handleClickOutside);
  }, []);

  return (
    <div ref={dropdownRef}>
      <button onClick={toggle}>Toggle</button>
      {open && <div className="menu">Menu Content</div>}
    </div>
  );
};

πŸ’¬ Real-World Scenarios

  • Messenger: Clicking messages, replying

  • Trello: Clicking cards, opening modals

  • Instagram: Clicking heart or comment under a photo


🎯 Interview Questions

Sure! Here's a clean and concise answer set for each of those JavaScript and React interview questions on event delegation, tailored from beginner to advanced level:


🟒 Beginner

1. What is event delegation?

Event delegation is a technique where a single event listener is added to a parent element, and it monitors events from its child elements by using event bubbling. Instead of attaching listeners to each child, you handle them from one centralized place.

2. Why is it better than attaching multiple listeners?

  • It improves performance by reducing the number of listeners in the DOM.

  • It makes your code cleaner and easier to manage.

  • It works well with dynamically added elements (e.g., adding new list items via JS).

3. What is event.target?

event.target refers to the actual DOM element that was clicked or interacted with β€” not necessarily the element that has the listener attached.


🟑 Intermediate

4. What is stopPropagation() and when would you use it?

stopPropagation() is a method on the event object that prevents the event from bubbling up to parent elements.
Use it when you don’t want a parent element’s event listener to run after an event on a child element.

5. How do you handle events on dynamic elements?

Use event delegation β€” attach the listener to a static parent element and check event.target or use closest() to identify which dynamic child was interacted with.


πŸ”΄ Advanced

6. Difference between event.currentTarget and event.target?

  • event.target: The actual element that triggered the event.

  • event.currentTarget: The element the event handler is attached to.
    This distinction is important when you’re using delegation and want to know where the handler was set vs. what was clicked.

7. What issues might you face with deeply nested delegation?

  • Targeting the correct element can become tricky in complex DOM structures.

  • Performance may degrade if you traverse deep trees inefficiently.

  • event.target might reference an unintended nested child, so you may need to use closest() or extra checks.

8. How would you apply event delegation to infinite scroll comments?

  • Attach a single click or scroll listener to the parent container of the comments.

  • As new comment elements are added dynamically, the same listener continues to work.

  • Use logic inside the handler to check if the event came from a comment or reply button (e.g., via e.target.dataset, class, or closest()).


πŸ”š Final Tips

  • Use delegation to reduce memory footprint

  • Combine with closest() and dataset for powerful targeting

  • Always clean up listeners in useEffect

Happy coding! πŸ”₯


✍️ Written by Krishan β€” follow me on Twitter and GitHub and Linkedin

πŸ’‘ Check out the current code examples and notes repo: GitHub

πŸ“ Read more on my blog: Hashnode

10
Subscribe to my newsletter

Read articles from krishan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

krishan
krishan

πŸ‘‹ Hey, I'm a Frontend Developer passionate about building clean, user-friendly interfaces. πŸš€ Learning and sharing everything from React, JavaScript, HTML/CSS to advanced topics like Data Structures, Algorithms & System Design. πŸ’» Documenting my journey from fundamentals to becoming a top-tier developer β€” one blog at a time. πŸ“š Join me as I break down complex topics into easy, practical lessons β€” with GitHub repos, code snippets, and real-world examples. πŸ” Consistent growth, community learning, and aiming high!