React has its own event system that's similar to the DOM event system, but that works in parallel to it. That means that React event handlers are assigned differently than DOM event listeners.
React Event Handlers
You can handle events in React by passing an event handler function as a prop JSX element:
The event handler props are all camel-cased and accept a callback function. Some commonly used ones are onClick
, onChange
and onSubmit
. The callback function will receive SyntheticEvent as the parameter.
DOM Event Handlers in React
It's sometimes necessary to use the DOM event system, for instance when integrating with 3rd party libraries or listening to window
events.
You should use the useEffect
hook to add event listeners in React. Here's how to listen to events on window
in React:
- Add a call to
useEffect
and provide[]
as the dependency list to only register the event listener once when the component is mounted. - Create a handler function inside of the
useEffect
hook's callback function. - Bind the event handler to an event using
addEventListener
on the DOM element. - Return a cleanup function for the
useEffect
hook that removes the assigned event handler.
Assigning DOM events to React elements
To assign the event listener to the React element you need to first get the reference to the underlying DOM element. This is commonly done using the useRef
hook:
- Call the
useRef
and assign its value to theref
prop on the React element. - In the
useEffect
hook, get the reference to the DOM element fromcurrent
property on the ref object. Check that it's not null. - Add the DOM event listener like before using
addEventListener
.
Conclusion
Always prefer to use the React event system, because it fixes certain inconsistencies, and working with it is generally easier.
In the rare cases when you do need DOM event listeners, assign them in the useEffect
hook. You should first have the reference to the DOM element which you can get using the useRef
hook or simply by querying it directly, e.g. window
, document.body
or document.querySelector(...)
.