Synthetic Events in React

A detailed guide to understanding and using synthetic events in React, covering types, handling, and best practices.

Introduction to Synthetic Events

What are Synthetic Events?

Imagine you're building a bustling city where every action, from a car honking to a fire alarm ringing, needs to be managed and responded to efficiently. In the world of web development with React, synthetic events play a similar role. Synthetic events are a cross-browser wrapper around the browser's native event system. This means that React takes the native events and wraps them with a layer that ensures they work consistently across all browsers. Think of synthetic events as a universal translator for user interactions in your web applications.

Purpose of Synthetic Events

The primary purpose of synthetic events is to provide a consistent interface for handling events across different browsers. Before React introduced synthetic events, developers had to write complex event handling code to work around inconsistencies in how browsers implemented event systems. By standardizing event handling, React simplifies the process and ensures that your event handling code works reliably across all major browsers without needing to worry about browser-specific quirks.

Benefits of Using Synthetic Events

  1. Consistency: Synthetic events provide a consistent interface for event handling across different browsers. This means that the same event handler code will work the same way in Chrome, Firefox, Safari, Edge, and Internet Explorer.
  2. Performance: React bundles all event handlers into a single event pool, which reduces memory footprint and improves performance. This is like having a central dispatch center manage all events in your city, rather than having individual dispatch centers for each type of event.
  3. Cross-Browser Compatibility: Dealing with cross-browser differences can be a nightmare. Synthetic events take care of these differences internally, allowing you to focus on building your application rather than fixing browser-specific bugs.
  4. Delegation: Synthetic events use event delegation under the hood. This means that all events are handled at the top level, reducing the number of event listeners attached to the DOM, which improves performance. Think of this as having a single point of contact for all city-wide events, rather than having individual points of contact for each neighborhood.

Getting Started with Synthetic Events

Overview of Event Handling in React

In React, event handling is quite similar to handling events in regular HTML, but with some differences due to React's synthetic event system. In HTML, you would typically attach event handlers directly to elements using attributes like onclick, onsubmit, and onchange. In React, these attributes are used in JSX to define event handlers, but they are treated as props.

Basic Structure of Event Handling

The basic structure of event handling in React involves attaching an event handler to a component using a prop, and defining the function that will be executed when the event is triggered. Here's a simple example to illustrate this:

import React, { Component } from 'react';

class ButtonComponent extends Component {
  handleClick = () => {
    alert('Button was clicked!');
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click Me
      </button>
    );
  }
}

export default ButtonComponent;

In this example, we have a ButtonComponent that contains a button element. The onClick prop of the button is set to the handleClick method. When the button is clicked, the handleClick method is executed, and an alert box is displayed.

Event Handling Syntax

Event handling in React can be done in several ways, depending on the component type and your coding style. Let's explore the most common methods.

Inline Event Handlers in JSX

You can define inline arrow functions for event handlers directly in JSX. This is useful for simple event handlers but can cause performance issues with each render due to the creation of a new function instance on each render cycle.

import React, { Component } from 'react';

class InlineEventComponent extends Component {
  render() {
    return (
      <button onClick={() => alert('Button was clicked!')}>
        Click Me
      </button>
    );
  }
}

export default InlineEventComponent;

In this example, the onClick event handler is defined directly within the JSX. Each time the component renders, a new function is created for the onClick handler. This can be inefficient for complex or frequently triggered events.

Event Handler Methods in Class Components

In class components, it's common to define event handlers as methods of the component class. This method is more efficient and recommended for class components because it avoids creating a new function on each render.

import React, { Component } from 'react';

class MethodEventComponent extends Component {
  handleClick() {
    alert('Button was clicked!');
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click Me
      </button>
    );
  }
}

export default MethodEventComponent;

In this example, handleClick is a method of the MethodEventComponent class. By referencing this.handleClick, we avoid creating a new function on each render. However, if you don't bind the method, you'll encounter issues with the this context. To fix this, you can bind the method in the constructor or use arrow functions.

Here's how you can bind the method in the constructor:

import React, { Component } from 'react';

class MethodEventComponent extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert('Button was clicked!');
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click Me
      </button>
    );
  }
}

export default MethodEventComponent;

Alternatively, you can use an arrow function to define the method in the class body:

import React, { Component } from 'react';

class MethodEventComponent extends Component {
  handleClick = () => {
    alert('Button was clicked!');
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click Me
      </button>
    );
  }
}

export default MethodEventComponent;

Both approaches avoid creating a new function on each render and ensure that the this context is correct.

Event Handler Functions in Functional Components

In functional components, you can define event handlers as regular functions or use inline arrow functions within JSX. Functional components don't have this state, so they don't require binding. Here's how you can define an event handler in a functional component:

import React from 'react';

function FunctionalEventComponent() {
  const handleClick = () => {
    alert('Button was clicked!');
  };

  return (
    <button onClick={handleClick}>
      Click Me
    </button>
  );
}

export default FunctionalEventComponent;

In this example, handleClick is a regular function that is assigned to the onClick prop of the button.

Common Synthetic Event Types

React supports a wide variety of synthetic events, which correspond to native browser events. These events are categorized into different types, such as mouse events, keyboard events, and form events. Let's explore some of the most common synthetic event types in more detail.

Mouse Events

Mouse events are triggered by mouse interactions with elements on the page.

onClick

The onClick event is triggered when a user clicks an element.

import React from 'react';

function ClickExample() {
  const handleClick = () => {
    alert('Element was clicked!');
  };

  return (
    <div onClick={handleClick}>
      Click Me
    </div>
  );
}

export default ClickExample;

In this example, clicking the div element will trigger the handleClick function, displaying an alert message.

onDoubleClick

The onDoubleClick event is triggered when a user double-clicks an element.

import React from 'react';

function DoubleClickExample() {
  const handleDoubleClick = () => {
    alert('Element was double-clicked!');
  };

  return (
    <div onDoubleClick={handleDoubleClick}>
      Double Click Me
    </div>
  );
}

export default DoubleClickExample;

Here, double-clicking the div element triggers the handleDoubleClick function.

onMouseDown

The onMouseDown event is triggered when a mouse button is pressed down over an element.

import React from 'react';

function MouseDownExample() {
  const handleMouseDown = () => {
    alert('Mouse button was pressed down!');
  };

  return (
    <div onMouseDown={handleMouseDown}>
      Press Mouse Down
    </div>
  );
}

export default MouseDownExample;

Clicking down the mouse button on the div element will trigger the handleMouseDown function.

onMouseEnter

The onMouseEnter event is triggered when the mouse pointer is moved onto an element.

import React from 'react';

function MouseEnterExample() {
  const handleMouseEnter = () => {
    alert('Mouse entered the element!');
  };

  return (
    <div onMouseEnter={handleMouseEnter}>
      Move Mouse Over Me
    </div>
  );
}

export default MouseEnterExample;

Moving the mouse over the div element triggers the handleMouseEnter function.

onMouseLeave

The onMouseLeave event is triggered when the mouse pointer is moved off an element.

import React from 'react';

function MouseLeaveExample() {
  const handleMouseLeave = () => {
    alert('Mouse left the element!');
  };

  return (
    <div onMouseLeave={handleMouseLeave}>
      Move Mouse Away from Me
    </div>
  );
}

export default MouseLeaveExample;

Moving the mouse away from the div element triggers the handleMouseLeave function.

onMouseMove

The onMouseMove event is triggered when the mouse pointer is moved over an element.

import React from 'react';

function MouseMoveExample() {
  const handleMouseMove = () => {
    console.log('Mouse is moving over the element!');
  };

  return (
    <div onMouseMove={handleMouseMove}>
      Move Mouse Over Me
    </div>
  );
}

export default MouseMoveExample;

Moving the mouse over the div element will continuously trigger the handleMouseMove function.

onMouseOut

The onMouseOut event is triggered when the mouse pointer is moved off an element.

import React from 'react';

function MouseOutExample() {
  const handleMouseOut = () => {
    alert('Mouse moved out of the element!');
  };

  return (
    <div onMouseOut={handleMouseOut}>
      Move Mouse Out
    </div>
  );
}

export default MouseOutExample;

Moving the mouse outside the div element triggers the handleMouseOut function.

onMouseOver

The onMouseOver event is triggered when the mouse pointer is moved onto an element.

import React from 'react';

function MouseOverExample() {
  const handleMouseOver = () => {
    alert('Mouse moved over the element!');
  };

  return (
    <div onMouseOver={handleMouseOver}>
      Move Mouse Over Me
    </div>
  );
}

export default MouseOverExample;

Moving the mouse over the div element triggers the handleMouseOver function.

onMouseUp

The onMouseUp event is triggered when a mouse button is released over an element.

import React from 'react';

function MouseUpExample() {
  const handleMouseUp = () => {
    alert('Mouse button was released over the element!');
  };

  return (
    <div onMouseUp={handleMouseUp}>
      Release Mouse Button
    </div>
  );
}

export default MouseUpExample;

Releasing the mouse button over the div element triggers the handleMouseUp function.

Keyboard Events

Keyboard events are triggered by keyboard actions.

onKeyDown

The onKeyDown event is triggered when a key is pressed down.

import React from 'react';

function KeyDownExample() {
  const handleKeyDown = (event) => {
    console.log(`Key ${event.key} was pressed down!`);
  };

  return (
    <input onKeyDown={handleKeyDown} placeholder="Press a key" />
  );
}

export default KeyDownExample;

Pressing down a key in the input field triggers the handleKeyDown function, logging the key pressed.

onKeyPress

The onKeyPress event is triggered when a key is pressed and released.

import React from 'react';

function KeypressExample() {
  const handleKeyPress = (event) => {
    console.log(`Key ${event.key} was pressed and released!`);
  };

  return (
    <input onKeyPress={handleKeyPress} placeholder="Press a key" />
  );
}

export default KeypressExample;

Pressing and releasing a key in the input field triggers the handleKeyPress function, logging the key pressed.

onKeyUp

The onKeyUp event is triggered when a key is released.

import React from 'react';

function KeyUpExample() {
  const handleKeyUp = (event) => {
    console.log(`Key ${event.key} was released!`);
  };

  return (
    <input onKeyUp={handleKeyUp} placeholder="Release a key" />
  );
}

export default KeyUpExample;

Releasing a key in the input field triggers the handleKeyUp function, logging the key released.

Clipboard Events

Clipboard events are triggered by clipboard actions.

onCopy

The onCopy event is triggered when the user copies content to the clipboard.

import React from 'react';

function CopyExample() {
  const handleCopy = (event) => {
    alert('Content was copied!');
  };

  return (
    <input onCopy={handleCopy} defaultValue="Try copying this text" />
  );
}

export default CopyExample;

Copying content from the input field triggers the handleCopy function.

onCut

The onCut event is triggered when the user cuts content from an element.

import React from 'react';

function CutExample() {
  const handleCut = (event) => {
    alert('Content was cut!');
  };

  return (
    <input onCut={handleCut} defaultValue="Try cutting this text" />
  );
}

export default CutExample;

Cutting content from the input field triggers the handleCut function.

onPaste

The onPaste event is triggered when the user pastes content into an element.

import React from 'react';

function PasteExample() {
  const handlePaste = (event) => {
    alert('Content was pasted!');
  };

  return (
    <input onPaste={handlePaste} placeholder="Try pasting some text" />
  );
}

export default PasteExample;

Pasting content into the input field triggers the handlePaste function.

Composition Events

Composition events are triggered during the composition of text, such as when using an IME (Input Method Editor).

onCompositionEnd

The onCompositionEnd event is triggered when the composition of a text input ends.

import React from 'react';

function CompositionEndExample() {
  const handleCompositionEnd = (event) => {
    console.log('Composition ended with value:', event.data);
  };

  return (
    <input onCompositionEnd={handleCompositionEnd} placeholder="Type here" />
  );
}

export default CompositionEndExample;

Ending the composition of text in the input field triggers the handleCompositionEnd function.

onCompositionStart

The onCompositionStart event is triggered when the composition of a text input starts.

import React from 'react';

function CompositionStartExample() {
  const handleCompositionStart = (event) => {
    console.log('Composition started with value:', event.data);
  };

  return (
    <input onCompositionStart={handleCompositionStart} placeholder="Type here" />
  );
}

export default CompositionStartExample;

Starting the composition of text in the input field triggers the handleCompositionStart function.

onCompositionUpdate

The onCompositionUpdate event is triggered whenever the composition text is updated.

import React from 'react';

function CompositionUpdateExample() {
  const handleCompositionUpdate = (event) => {
    console.log('Composition updated with value:', event.data);
  };

  return (
    <input onCompositionUpdate={handleCompositionUpdate} placeholder="Type here" />
  );
}

export default CompositionUpdateExample;

Updating the composition of text in the input field triggers the handleCompositionUpdate function.

Form Events

Form events are triggered by user interactions with form elements.

onChange

The onChange event is triggered when the value of an input, textarea, or select element changes.

import React, { useState } from 'react';

function ChangeExample() {
  const [value, setValue] = useState('');

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  return (
    <input
      type="text"
      value={value}
      onChange={handleChange}
      placeholder="Type something"
    />
  );
}

export default ChangeExample;

Changing the value of the input field triggers the handleChange function, updating the value state.

onInput

The onInput event is triggered for value changes caused by user input, such as typing, pasting, and cutting.

import React, { useState } from 'react';

function InputExample() {
  const [value, setValue] = useState('');

  const handleInput = (event) => {
    setValue(event.target.value);
  };

  return (
    <input
      type="text"
      value={value}
      onInput={handleInput}
      placeholder="Type something"
    />
  );
}

export default InputExample;

Making an input in the input field triggers the handleInput function, updating the value state.

onInvalid

The onInvalid event is triggered when a form element's value is invalid.

import React from 'react';

function InvalidExample() {
  const handleSubmit = (event) => {
    event.preventDefault();
    alert('Form submitted!');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="email" required />
      <button type="submit">Submit</button>
    </form>
  );
}

export default InvalidExample;

Submitting an invalid form triggers the handleSubmit function, which prevents the default form submission and displays an alert.

onSubmit

The onSubmit event is triggered when a form is submitted.

import React from 'react';

function SubmitExample() {
  const handleSubmit = (event) => {
    event.preventDefault();
    alert('Form submitted!');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" required />
      <button type="submit">Submit</button>
    </form>
  );
}

export default SubmitExample;

Submitting the form triggers the handleSubmit function, which prevents the default form submission and displays an alert.

Drag & Drop Events

Drag and drop events are triggered during the dragging and dropping of elements.

onDrag

The onDrag event is triggered while an element or text selection is being dragged.

import React from 'react';

function DragExample() {
  const handleDrag = () => {
    alert('Element is being dragged!');
  };

  return (
    <div draggable onDrag={handleDrag}>
      Drag Me
    </div>
  );
}

export default DragExample;

Dragging the div element triggers the handleDrag function.

onDragEnd

The onDragEnd event is triggered when a drag operation ends.

import React from 'react';

function DragEndExample() {
  const handleDragEnd = () => {
    alert('Drag operation ended!');
  };

  return (
    <div draggable onDragEnd={handleDragEnd}>
      Drag Me
    </div>
  );
}

export default DragEndExample;

Ending a drag operation on the div element triggers the handleDragEnd function.

onDragEnter

The onDragEnter event is triggered when an element enters a valid drop target during a drag operation.

import React from 'react';

function DragEnterExample() {
  const handleDragEnter = () => {
    alert('Element entered a drop target!');
  };

  return (
    <div onDragEnter={handleDragEnter} style={{ padding: '20px', border: '1px solid black' }}>
      Drop Target
    </div>
  );
}

export default DragEnterExample;

Drag entering the div element triggers the handleDragEnter function.

onDragExit

The onDragExit event is triggered when an element leaves a valid drop target during a drag operation.

import React from 'react';

function DragExitExample() {
  const handleDragExit = () => {
    alert('Element left a drop target!');
  };

  return (
    <div onDragExit={handleDragExit} style={{ padding: '20px', border: '1px solid black' }}>
      Drop Target
    </div>
  );
}

export default DragExitExample;

Drag exiting the div element triggers the handleDragExit function.

onDragLeave

The onDragLeave event is triggered when an element leaves a valid drop target during a drag operation.

import React from 'react';

function DragLeaveExample() {
  const handleDragLeave = () => {
    alert('Element left a drop target!');
  };

  return (
    <div onDragLeave={handleDragLeave} style={{ padding: '20px', border: '1px solid black' }}>
      Drop Target
    </div>
  );
}

export default DragLeaveExample;

Leaving the div element during a drag operation triggers the handleDragLeave function.

onDragOver

The onDragOver event is triggered when an element is being dragged over a valid drop target.

import React from 'react';

function DragOverExample() {
  const handleDragOver = (event) => {
    event.preventDefault(); // Prevent default action to allow drop
    alert('Element is being dragged over a drop target!');
  };

  return (
    <div onDragOver={handleDragOver} style={{ padding: '20px', border: '1px solid black' }}>
      Drop Target
    </div>
  );
}

export default DragOverExample;

Dragging over the div element triggers the handleDragOver function. The event.preventDefault() is used to allow dropping.

onDragStart

The onDragStart event is triggered when the user starts dragging an element.

import React from 'react';

function DragStartExample() {
  const handleDragStart = () => {
    alert('Drag operation started!');
  };

  return (
    <div draggable onDragStart={handleDragStart}>
      Drag Me
    </div>
  );
}

export default DragStartExample;

Starting the drag operation on the div element triggers the handleDragStart function.

onDrop

The onDrop event is triggered when an element is dropped on a valid drop target.

import React from 'react';

function DropExample() {
  const handleDragOver = (event) => {
    event.preventDefault(); // Prevent default action to allow drop
  };

  const handleDrop = (event) => {
    event.preventDefault();
    alert('Element was dropped!');
  };

  return (
    <div onDragOver={handleDragOver} onDrop={handleDrop} style={{ padding: '20px', border: '1px solid black' }}>
      Drop Target
    </div>
  );
}

export default DropExample;

Dropping an element on the div triggers the handleDrop function. The event.preventDefault() is used to allow dropping.

Media Events

Media events are triggered by media elements like audio and video.

onAbort

The onAbort event is triggered when the loading of a media is aborted by the user.

import React from 'react';

function AbortExample() {
  const handleAbort = () => {
    alert('Media loading aborted!');
  };

  return (
    <audio src="audio.mp3" onAbort={handleAbort} />
  );
}

export default AbortExample;

Aborting the loading of the audio file triggers the handleAbort function.

onCanPlay

The onCanPlay event is triggered when a media element can start playing.

import React from 'react';

function CanPlayExample() {
  const handleCanPlay = () => {
    alert('Media can play!');
  };

  return (
    <audio src="audio.mp3" onCanPlay={handleCanPlay} />
  );
}

export default CanPlayExample;

When the audio file can play, the handleCanPlay function is triggered.

onCanPlayThrough

The onCanPlayThrough event is triggered when a media element can be played to the end without interruption.

import React from 'react';

function CanPlayThroughExample() {
  const handleCanPlayThrough = () => {
    alert('Media can play through!');
  };

  return (
    <audio src="audio.mp3" onCanPlayThrough={handleCanPlayThrough} />
  );
}

export default CanPlayThroughExample;

When the audio file can play through to the end without interruption, the handleCanPlayThrough function is triggered.

onDurationChange

The onDurationChange event is triggered when the duration of a media element changes.

import React from 'react';

function DurationChangeExample() {
  const handleDurationChange = () => {
    alert('Media duration changed!');
  };

  return (
    <audio src="audio.mp3" onDurationChange={handleDurationChange} />
  );
}

export default DurationChangeExample;

Changing the duration of the audio file triggers the handleDurationChange function.

onEmptied

The onEmptied event is triggered when a media element has reached the end of its playback.

import React from 'react';

function EmptiedExample() {
  const handleEmptied = () => {
    alert('Media is emptied!');
  };

  return (
    <audio src="audio.mp3" onEmptied={handleEmptied} />
  );
}

export default EmptiedExample;

When the audio file reaches the end, the handleEmptied function is triggered.

onEncrypted

The onEncrypted event is triggered when a media element has encountered encrypted media.

import React from 'react';

function EncryptedExample() {
  const handleEncrypted = () => {
    alert('Media is encrypted!');
  };

  return (
    <video src="video.mp4" onEncrypted={handleEncrypted} />
  );
}

export default EncryptedExample;

When the video is encrypted, the handleEncrypted function is triggered.

onEnded

The onEnded event is triggered when a media element has reached the end of its playback.

import React from 'react';

function EndedExample() {
  const handleEnded = () => {
    alert('Media has ended!');
  };

  return (
    <video src="video.mp4" onEnded={handleEnded} />
  );
}

export default EndedExample;

When the video ends, the handleEnded function is triggered.

onError

The onError event is triggered when a media element encounters an error.

import React from 'react';

function ErrorExample() {
  const handleError = () => {
    alert('Error in media element!');
  };

  return (
    <video src="invalid-video.mp4" onError={handleError} />
  );
}

export default ErrorExample;

When the video encounters an error, the handleError function is triggered.

onLoadedData

The onLoadedData event is triggered when the media is loaded.

import React from 'react';

function LoadedDataExample() {
  const handleLoadedData = () => {
    alert('Media data is loaded!');
  };

  return (
    <audio src="audio.mp3" onLoadedData={handleLoadedData} />
  );
}

export default LoadedDataExample;

When the audio data is loaded, the handleLoadedData function is triggered.

onLoadedMetadata

The onLoadedMetadata event is triggered when the media's metadata has been loaded.

import React from 'react';

function LoadedMetadataExample() {
  const handleLoadedMetadata = () => {
    alert('Media metadata is loaded!');
  };

  return (
    <audio src="audio.mp3" onLoadedMetadata={handleLoadedMetadata} />
  );
}

export default LoadedMetadataExample;

When the audio metadata is loaded, the handleLoadedMetadata function is triggered.

onLoadStart

The onLoadStart event is triggered when the media starts to load.

import React from 'react';

function LoadStartExample() {
  const handleLoadStart = () => {
    alert('Media is starting to load!');
  };

  return (
    <audio src="audio.mp3" onLoadStart={handleLoadStart} />
  );
}

export default LoadStartExample;

When the audio starts loading, the handleLoadStart function is triggered.

onPause

The onPause event is triggered when the media is paused.

import React from 'react';

function PauseExample() {
  const handlePause = () => {
    alert('Media is paused!');
  };

  return (
    <video src="video.mp4" controls onPause={handlePause} />
  );
}

export default PauseExample;

Pausing the video triggers the handlePause function.

onPlay

The onPlay event is triggered when the media starts playing.

import React from 'react';

function PlayExample() {
  const handlePlay = () => {
    alert('Media is playing!');
  };

  return (
    <video src="video.mp4" controls onPlay={handlePlay} />
  );
}

export default PlayExample;

Playing the video triggers the handlePlay function.

onPlaying

The onPlaying event is triggered when the media starts playing after being paused or stopped for buffering.

import React from 'react';

function PlayingExample() {
  const handlePlaying = () => {
    alert('Media is playing!');
  };

  return (
    <video src="video.mp4" controls onPlaying={handlePlaying} />
  );
}

export default PlayingExample;

Playing the video after pausing or buffering triggers the handlePlaying function.

onProgress

The onProgress event is triggered periodically as the media is being loaded.

import React from 'react';

function ProgressExample() {
  const handleProgress = () => {
    console.log('Media is loading...');
  };

  return (
    <audio src="audio.mp3" controls onProgress={handleProgress} />
  );
}

export default ProgressExample;

While the audio is loading, the handleProgress function is triggered periodically.

onRateChange

The onRateChange event is triggered when the playback rate of the media changes.

import React from 'react';

function RateChangeExample() {
  const handleRateChange = () => {
    alert('Playback rate changed!');
  };

  return (
    <video src="video.mp4" controls onRateChange={handleRateChange} />
  );
}

export default RateChangeExample;

Changing the playback rate of the video triggers the handleRateChange function.

onSeeked

The onSeeked event is triggered when the seeking attribute is set to false and the seek operation completes.

import React from 'react';

function SeekedExample() {
  const handleSeeked = () => {
    alert('Seeking is complete!');
  };

  return (
    <video src="video.mp4" controls onSeeked={handleSeeked} />
  );
}

export default SeekedExample;

Completing the seeking operation on the video triggers the handleSeeked function.

onSeeking

The onSeeking event is triggered when the seeking attribute is set to true.

import React from 'react';

function SeekingExample() {
  const handleSeeking = () => {
    alert('Seeking started!');
  };

  return (
    <video src="video.mp4" controls onSeeking={handleSeeking} />
  );
}

export default SeekingExample;

Starting the seeking operation on the video triggers the handleSeeking function.

onStalled

The onStalled event is triggered when the media is stalled during playback.

import React from 'react';

function StalledExample() {
  const handleStalled = () => {
    alert('Media is stalled!');
  };

  return (
    <video src="video.mp4" controls onStalled={handleStalled} />
  );
}

export default StalledExample;

Stalling during video playback triggers the handleStalled function.

onSuspend

The onSuspend event is triggered when the browser intentionally does not continue fetching the media data.

import React from 'react';

function SuspendExample() {
  const handleSuspend = () => {
    alert('Media loading is suspended!');
  };

  return (
    <audio src="audio.mp3" controls onSuspend={handleSuspend} />
  );
}

export default SuspendExample;

Suspending the loading of the audio triggers the handleSuspend function.

onTimeUpdate

The onTimeUpdate event is triggered when the current playback position of a media element changes.

import React from 'react';

function TimeUpdateExample() {
  const handleTimeUpdate = () => {
    console.log('Media time updated!');
  };

  return (
    <video src="video.mp4" controls onTimeUpdate={handleTimeUpdate} />
  );
}

export default TimeUpdateExample;

Updating the playback position of the video triggers the handleTimeUpdate function.

onVolumeChange

The onVolumeChange event is triggered when the volume of a media element changes.

import React from 'react';

function VolumeChangeExample() {
  const handleVolumeChange = () => {
    alert('Volume changed!');
  };

  return (
    <video src="video.mp4" controls onVolumeChange={handleVolumeChange} />
  );
}

export default VolumeChangeExample;

Changing the volume of the video triggers the handleVolumeChange function.

onWaiting

The onWaiting event is triggered when the media has paused but not because of an error, end of the media, or user action.

import React from 'react';

function WaitingExample() {
  const handleWaiting = () => {
    alert('Media is waiting!');
  };

  return (
    <video src="video.mp4" controls onWaiting={handleWaiting} />
  );
}

export default WaitingExample;

When the video is waiting, the handleWaiting function is triggered.

Image Events

Image events are triggered by user interactions with image elements.

onLoad

The onLoad event is triggered when an image has finished loading.

import React from 'react';

function LoadExample() {
  const handleLoad = () => {
    alert('Image is loaded!');
  };

  return (
    <img src="image.jpg" onLoad={handleLoad} alt="Example Image" />
  );
}

export default LoadExample;

Loading the image triggers the handleLoad function.

onError

The onError event is triggered when an image fails to load.

import React from 'react';

function ErrorExample() {
  const handleError = () => {
    alert('Image failed to load!');
  };

  return (
    <img src="invalid-image.jpg" onError={handleError} alt="Example Image" />
  );
}

export default ErrorExample;

Failing to load the image triggers the handleError function.

Selection Events

Selection events are triggered by user text selections in form elements.

onSelect

The onSelect event is triggered when the text in an element is selected.

import React from 'react';

function SelectExample() {
  const handleSelect = () => {
    alert('Text was selected!');
  };

  return (
    <input onSelect={handleSelect} placeholder="Select text here" />
  );
}

export default SelectExample;

Selecting text in the input field triggers the handleSelect function.

Transition Events

Transition events are triggered by CSS transitions.

onTransitionEnd

The onTransitionEnd event is triggered when a CSS transition has completed.

import React from 'react';

function TransitionEndExample() {
  const handleTransitionEnd = () => {
    alert('Transition ended!');
  };

  return (
    <div style={{ width: '100px', height: '100px', backgroundColor: 'red', transition: 'width 2s' }} onClick={() => console.log('Changing width')}>
      Transition
    </div>
  );
}

export default TransitionEndExample;

Ending a CSS transition on the div triggers the handleTransitionEnd function.

Animation Events

Animation events are triggered by CSS animations.

onAnimationStart

The onAnimationStart event is triggered when a CSS animation starts.

import React from 'react';

function AnimationStartExample() {
  const handleAnimationStart = () => {
    alert('Animation started!');
  };

  return (
    <div
      style={{
        width: '100px',
        height: '100px',
        backgroundColor: 'blue',
        animation: 'example 2s',
        '@keyframes example': {
          from { backgroundColor: 'blue'; },
          to { backgroundColor: 'green'; }
        }
      }}
      onAnimationStart={handleAnimationStart}
    >
      Animation
    </div>
  );
}

export default AnimationStartExample;

Starting a CSS animation on the div triggers the handleAnimationStart function.

onAnimationEnd

The onAnimationEnd event is triggered when a CSS animation ends.

import React from 'react';

function AnimationEndExample() {
  const handleAnimationEnd = () => {
    alert('Animation ended!');
  };

  return (
    <div
      style={{
        width: '100px',
        height: '100px',
        backgroundColor: 'blue',
        animation: 'example 2s',
        '@keyframes example': {
          from { backgroundColor: 'blue'; },
          to { backgroundColor: 'green'; }
        }
      }}
      onAnimationEnd={handleAnimationEnd}
    >
      Animation
    </div>
  );
}

export default AnimationEndExample;

Ending a CSS animation on the div triggers the handleAnimationEnd function.

onAnimationIteration

The onAnimationIteration event is triggered when a CSS animation repeats.

import React from 'react';

function AnimationIterationExample() {
  const handleAnimationIteration = () => {
    alert('Animation iteration!');
  };

  return (
    <div
      style={{
        width: '100px',
        height: '100px',
        backgroundColor: 'blue',
        animation: 'example 2s infinite',
        '@keyframes example': {
          from { backgroundColor: 'blue'; },
          to { backgroundColor: 'green'; }
        }
      }}
      onAnimationIteration={handleAnimationIteration}
    >
      Animation
    </div>
  );
}

export default AnimationIterationExample;

Iterating a CSS animation on the div triggers the handleAnimationIteration function.

Modifying Synthetic Events

Modifier methods are available for modifying the event.

Preventing Default Behavior

Using preventDefault

The preventDefault method can be used to prevent the default action associated with an event.

import React from 'react';

function PreventDefaultExample() {
  const handleSubmit = (event) => {
    event.preventDefault();
    alert('Form submitted!');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" />
      <button type="submit">Submit</button>
    </form>
  );
}

export default PreventDefaultExample;

Submitting the form triggers the handleSubmit function, which prevents the default form submission and displays an alert.

Stopping Event Propagation

Using stopPropagation

The stopPropagation method can be used to stop the event from propagating up the DOM tree.

import React from 'react';

function StopPropagationExample() {
  const handleDivClick = () => {
    alert('Div was clicked!');
  };

  const handleButtonClick = (event) => {
    event.stopPropagation();
    alert('Button was clicked!');
  };

  return (
    <div onClick={handleDivClick}>
      <button onClick={handleButtonClick}>
        Click Me
      </button>
    </div>
  );
}

export default StopPropagationExample;

Clicking the button triggers the handleButtonClick function, which stops the event from propagating to the div.

Using stopImmediatePropagation

The stopImmediatePropagation method can be used to stop the event from propagating further and prevent other event listeners from running.

import React from 'react';

function StopImmediatePropagationExample() {
  const handleDivClick = () => {
    alert('Div was clicked!');
  };

  const handleButtonClick = (event) => {
    event.stopImmediatePropagation();
    alert('Button was clicked!');
  };

  return (
    <div onClick={handleDivClick}>
      <button onClick={handleButtonClick}>
        Click Me
      </button>
    </div>
  );
}

export default StopImmediatePropagationExample;

Clicking the button triggers the handleButtonClick function, which stops the event from propagating further and prevents the handleDivClick function from running.

Multi-Event Handlers

Adding Multiple Handlers to a Single Element

You can add multiple handlers to a single element by chaining them together.

import React from 'react';

function MultipleHandlersExample() {
  const handleFirstClick = () => {
    alert('First click handler!');
  };

  const handleSecondClick = () => {
    alert('Second click handler!');
  };

  return (
    <div onClick={() => {
      handleFirstClick();
      handleSecondClick();
    }}>
      Click Me
    </div>
  );
}

export default MultipleHandlersExample;

Clicking the div element triggers both handleFirstClick and handleSecondClick functions.

Separate Event Handlers for Different Events

You can define separate event handlers for different events on the same element.

import React from 'react';

function SeparateHandlersExample() {
  const handleMouseDown = () => {
    alert('Mouse button was pressed down!');
  };

  const handleMouseUp = () => {
    alert('Mouse button was released!');
  };

  return (
    <div onMouseDown={handleMouseDown} onMouseUp={handleMouseUp}>
      Click Me
    </div>
  );
}

export default SeparateHandlersExample;

Pressing down and releasing the mouse button over the div element triggers the handleMouseDown and handleMouseUp functions, respectively.

Conditional Event Handling

Using Conditional Rendering in Event Handlers

You can use conditional rendering in event handlers to perform different actions based on certain conditions.

import React, { useState } from 'react';

function ConditionalRenderingExample() {
  const [clicked, setClicked] = useState(false);

  const handleClick = () => {
    if (!clicked) {
      alert('Button was clicked!');
      setClicked(true);
    } else {
      alert('Button was already clicked!');
    }
  };

  return (
    <button onClick={handleClick}>
      Click Me
    </button>
  );
}

export default ConditionalRenderingExample;

Clicking the button triggers the handleClick function, which uses conditional rendering to display different alerts based on the clicked state.

Using Conditional Logic to Handle Different Events

You can use conditional logic to handle different events in the same handler.

import React from 'react';

function ConditionalEventExample() {
  const handleEvent = (event) => {
    if (event.type === 'click') {
      alert('Element was clicked!');
    } else if (event.type === 'dblclick') {
      alert('Element was double-clicked!');
    }
  };

  return (
    <div onClick={handleEvent} onDoubleClick={handleEvent}>
      Click or Double Click Me
    </div>
  );
}

export default ConditionalEventExample;

Clicking or double-clicking the div element triggers the handleEvent function, which uses conditional logic to display different alerts based on the event type.

Custom Events and Event Props

Creating Custom Events

You can create custom events to handle specific actions in your application.

import React, { createRef, Component } from 'react';

class CustomEventExample extends Component {
  constructor(props) {
    super(props);
    this.inputRef = createRef();
  }

  componentDidMount() {
    this.inputRef.current.addEventListener('customEvent', this.handleCustomEvent);
  }

  componentWillUnmount() {
    this.inputRef.current.removeEventListener('customEvent', this.handleCustomEvent);
  }

  handleCustomEvent = (event) => {
    alert('Custom event triggered with data:', event.detail);
  }

  render() {
    return (
      <input
        ref={this.inputRef}
        type="text"
        onClick={() => this.inputRef.current.dispatchEvent(new CustomEvent('customEvent', { detail: 'Hello' }))}
      />
    );
  }
}

export default CustomEventExample;

Clicking the input field triggers a custom event, which is handled by the handleCustomEvent function.

Passing Custom Event Props

You can pass custom properties to your events.

import React, { createRef, Component } from 'react';

class CustomEventPropsExample extends Component {
  constructor(props) {
    super(props);
    this.inputRef = createRef();
  }

  componentDidMount() {
    this.inputRef.current.addEventListener('customEvent', this.handleCustomEvent);
  }

  componentWillUnmount() {
    this.inputRef.current.removeEventListener('customEvent', this.handleCustomEvent);
  }

  handleCustomEvent = (event) => {
    alert('Custom event triggered with data:', event.detail);
  }

  render() {
    return (
      <input
        ref={this.inputRef}
        type="text"
        onClick={() => this.inputRef.current.dispatchEvent(new CustomEvent('customEvent', { detail: 'Hello' }))}
      />
    );
  }
}

export default CustomEventPropsExample;

Clicking the input field triggers a custom event with custom data, which is handled by the handleCustomEvent function.

Handling Custom Events in Components

You can handle custom events in components using the same approach as standard events.

import React, { createRef, Component } from 'react';

class CustomEventHandlerExample extends Component {
  constructor(props) {
    super(props);
    this.inputRef = createRef();
  }

  componentDidMount() {
    this.inputRef.current.addEventListener('customEvent', this.handleCustomEvent);
  }

  componentWillUnmount() {
    this.inputRef.current.removeEventListener('customEvent', this.handleCustomEvent);
  }

  handleCustomEvent = (event) => {
    alert('Custom event triggered with data:', event.detail);
  }

  render() {
    return (
      <input
        ref={this.inputRef}
        type="text"
        onClick={() => this.inputRef.current.dispatchEvent(new CustomEvent('customEvent', { detail: 'Hello' }))}
      />
    );
  }
}

export default CustomEventHandlerExample;

Handling a custom event in a component involves using the same approach as standard events.

Best Practices for Using Synthetic Events

Consistent Event Naming

Always use consistent event naming conventions to maintain readability and maintainability of your code.

Performance Considerations

Optimize performance by avoiding inline arrow functions in JSX. Instead, define event handlers as methods or functions outside of the render method to avoid creating new function instances on each render.

Event Handling in Controlled Components

Ensure that event handling in controlled components updates the state to reflect the current value of the input.

Conclusion and Next Steps

Recap of Key Points

  • Synthetic events are a cross-browser wrapper around the browser's native event system, providing a consistent interface for event handling.
  • React supports a wide variety of synthetic event types, including mouse events, keyboard events, form events, drag and drop events, media events, image events, selection events, transition events, and animation events.
  • Event handlers can be defined in various ways, such as inline event handlers, event handler methods in class components, and event handler functions in functional components.
  • Modifier methods like preventDefault and stopPropagation can be used to modify the behavior of events.
  • Custom events can be created and handled in components using the same approach as standard events.

Summary of Important Concepts

  • Synthetic events provide a consistent interface for event handling across different browsers.
  • React supports a wide variety of synthetic events that correspond to native browser events.
  • Event handlers can be defined using inline functions, class methods, or functional component functions.
  • Modifier methods like preventDefault and stopPropagation can be used to control the behavior of events.
  • Custom events can be created and handled using the same approach as standard events.

Moving Forward with React Event Handling

With a solid understanding of synthetic events in React, you're now ready to handle a wide variety of user interactions in your applications. By leveraging the powerful and flexible synthetic event system, you can create rich, interactive user interfaces that work smoothly across all browsers.

Continue to explore the rich set of event types provided by React, and experiment with different event handling techniques to build more complex and dynamic applications. Happy coding!