Responding to Events: Vanilla JS vs React
Tags: react, eventhandling, javascript
Published: 2024-06-18 12:00:35



> _Without event handling, websites would be like mannequins in a store window - nice to look at, but unable to respond. Let's bring them to life! - Unknown_

##Introduction
Handling user interactions efficiently is an important part of web development. I recently had to do a presentation on [Responding to Events](https://react.dev/learn/responding-to-events) with React which inspired this article where we will compare how to handle events using vanilla [JavaScript](https://javascript.info/) and [React](https://react.dev/).

Imagine a website as a conversation. Event handling allows the website to "listen" to your interactions (clicks, scrolls, etc.) and "respond" accordingly, making for an interactive and enjoyable experience. This article explores how event handling works in both Vanilla JavaScript and React, helping you choose the right tool for bringing your web interfaces to life.


## Vanilla JavaScript: Responding to Events

In vanilla JavaScript, you directly interact with the DOM to add event listeners and handle events. 
*The DOM(Document Object Model) represents all page content as objects that can be modified. You can read more about it here [DOM](https://javascript.info/browser-environment#dom-document-object-model).*
Here's a simple example showing how to change content and add new elements in response to user actions:

```HTML
<!DOCTYPE html>
<html>
<head>
  <title>Event Handling with Aidee</title>
</head>
<body>
  <div id="content">
    <p class="text">Welcome to Aidee's World!</p>
  </div>
  <button id="changeContent">Change Content</button>
  <button id="addElement">Add Element</button>

  <script>
    // Selecting elements
    const content = document.getElementById('content');
    const changeContentButton = document.getElementById('changeContent');
    const addElementButton = document.getElementById('addElement');

    // Changing content
    changeContentButton.addEventListener('click', () => {
      const paragraph = content.querySelector('.text');
      paragraph.textContent = 'My favourite colours are purple and black.';
      paragraph.style.color = 'purple';
    });

    // Adding a new element
    addElementButton.addEventListener('click', () => {
      const newParagraph = document.createElement('p');
      newParagraph.textContent = 'I am a new paragraph!';
      content.appendChild(newParagraph);
    });
  </script>
</body>
</html>
```
The code snippet:
-  uses `getElementById` to select the container element (content) and buttons by their unique IDs.
- adds an event listener on the "Change Content" button. Which when clicked, uses a `querySelector` to find the paragraph element with the class `.text` and modify its content and style.
- adds another event listener on the "Add Element" button.
Which when clicked, creates a new paragraph element, sets the new paragraph's text content and finally appends it to the parent element.

While Vanilla JavaScript offers a solid foundation for event handling, managing dynamic and interactive UIs with direct DOM manipulation can be challenging. This is where React comes into play.


## React: Responding to Events

React provides a component-based approach that simplifies UI updates and makes event handling more effective. Here’s how we can achieve the same functionality with React.

```jsx
import React, { useState } from 'react';

function App() {
  // useState hook to manage paragraph content and color
  const [paragraphs, setParagraphs] = useState([
    { text: "Welcome to Aidee's World!", color: 'black' },
  ]);

  // function to change content and color
  const changeContent = () => {
    setParagraphs([
      { text: 'My favourite colours are purple and black.', color: 'purple' },
    ]);
  };

  // function to add a new element and update text
  const addElement = () => {
    setParagraphs([...paragraphs, { text: 'I am a new paragraph!' }]);
  };

  return (
    <div id="content">
      {paragraphs.map((paragraph) => (
        <p key={paragraph.text} className="text" style={{ color: paragraph.color }}>
          {paragraph.text}
        </p>
      ))}
      <button onClick={changeContent}>Change Content</button>
      <button onClick={addElement}>Add Element</button>
    </div>
  );
}

export default App;
```

The code snippet:
- imports the necessary modules: React and the `useState` hook for managing state and defines a functional React component named App.
- declares a state variable called `paragraphs` using the `useState` hook. The initial state is set as an array containing an object with properties text and color for the first paragraph.
- creates two functions `changeContent` which updates the entire `paragraphs` state and `addElement` which adds a new object to the `paragraphs` state.
- uses `return` to define what the component will render on the screen.


##Comparative Analysis of Key Differences

| **Aspect**             | **Vanilla JavaScript**                                      | **React**                                             |
|--------------------|---------------------------------------------------------|---------------------------------------------------|
| **Event Handling**  | Uses methods like `addEventListener` to manually attach event listeners directly to DOM elements.         | Event handlers are defined within JSX attributes (e.g., `onClick`). These attributes are bound to component methods during rendering.    |
| **Event Handling Syntax** | Event handlers are separate functions that take an event object as an argument, allowing you to access details about the event from this object. | Event handlers are usually methods defined within a component class or functional component and they can directly access the component's state and props. |
| **Code Readability** | Can become cluttered with complex UI logic.              | Cleaner and more maintainable due to component structure. |
| **DOM Manipulation** | Needs manual DOM manipulation to update the UI after an event. This involves using methods like `createElement`, `appendChild`, or directly modifying element properties. | Uses the virtual DOM to manage updates. Changes are defined within event handlers, and React automatically re-renders the component to show the UI changes. |
| **State Management** | Doesn't have a built-in state management system so uses manual management which often leads to complex code.         | Provides a state management system using the `useState` hook or class properties. State updates trigger re-renders, ensuring the UI reflects the latest state. |
| **Performance**    | Direct manipulation can be more performant but harder to maintain. | Virtual DOM optimizes updates but adds abstraction. |



## Conclusion

Understanding the basics of JavaScript DOM manipulation provides a solid foundation for appreciating the advantages of React. While vanilla JavaScript gives you direct control over the DOM, React makes event handling easier and more efficient. By using React, you can build dynamic, interactive user interfaces more quickly and with less hassle. Transitioning from vanilla JavaScript to React can significantly improve your development process, allowing you to focus more on creating features and less on managing the details of DOM manipulation.