React synthetic events
Tags: react, syntheticevents, web, javascript
Published: 2020-07-28 21:27:02

---
title: React synthetic events
published: true
description: how React deals with events: React listens to every event at the document level, after receiving an event from the browser, React wraps this event with a wrapper that has the same interface as the native browser event
tags: #react #syntheticEvents #web #javascript
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8vha0a3nsc21l57bgw6w.jpeg
---
I would like a fresh start 😇

**React**
   A JavaScript library used to build vivid shiny user interfaces🥰.

**Event**
   The different ways the user uses to interact with an application, e.g. click, mouseover, input… etc
 
**Synthetic** 
	It is a ...🤔 Let's understand how React deals with events first.

React listens to every event at the document level, after receiving an event from the browser, React wraps this event with a wrapper that has the same interface as the native browser event, which means we still can use methods like `preventDefault()`.

So what is the need for this wrapper?!!😏

think of a situation where the exact same event has different names across different browsers.

imagine an event that fires when the user winks😉, this event in chrome called **A** in Safari called **B**, in such case, we will need to make different implementations for each browser😵.

What this wrapper does is registering all the different names for the same event effect, _**winking** in our case_, with only one name, so in a case when we want to listen to our winking effect instead of being listening to **A** for chrome and **B** for Safari we just use **onWink**, which is the wrapper react creates around the real event.

So whenever we are triggering an event in a React component, we are not actually dealing with the real DOM event, instead, we are dealing with React's custom event type, **a synthetic event**.

Now close your eyes😴, but not this kind of closing😅, and in your memory remember all the onClick(s), onBlur(s), onChange(s) you have ever used in your react components, these are not the real ones, these are react's synthetic events😇.

So we do not have to think anymore about different browsers implementations, react makes creating cross-browsers applications much less painful, which means we can concentrate more on adding browsers prefixes to our CSS properties😅.
 
This is not the end, as this is not the only bright side of React's synthetic events😃. Another catchy benefit of synthetic events is that React reuses these events objects, by pooling them, which results in performance gains.

Once the event handler is invoked, _an event handler is a method executed once an event is triggered_, all the properties on this event object will be nullified, _set to their empty/default states_, to be ready to be reused again.

Till this point, everything looks amazing, and you might feel🧐, but you might also go through some 🤨, 🙄, or even 😤 moments once you see **Warning: This synthetic event is reused for performance reasons in the browser**.
 
What makes most of us go through 🤨, 🙄, and 😤 moments, is not that despite it is warning it is written in red, but it is actually accessing any event properties in the event handler function fails

Imagine the following:

```js
import React, { useState } from "react"

const ExampleComponent = (() => {
  const [counter, setCounter] = useState()

  function handelArrowBtn(event) {
    if (event.keyCode === 40) { //down arrow button
      setCounter(counter - 1)
    } else if (event.keyCode === 38) { // up arrow button
      setCounter(counter + 1)
    }
  }

  return (
    <div>
      <input
        type="number"
        value={counter}
        onKeyDown={handelArrowBtn}
       />
    </div>
  )
})

export default ExampleComponent
```
This counter will neither be increased nor decreased. And our lovely red warning will be printed in the browser console.

###Let's see what is happening here...

After the event handler function, _`handelArrowBtn()` in our case_, is invoked the object of our synthetic event, `onKeyDown` in our case, gets nullified, the old values to the keys within this object are no longer exist, the event object returned to its original state to be ready to be reused, and as this is an object, so our `handelArrowBtn()` has access to it by reference which means our function now has access to the event object with its original state(nullified version).

####So, how can we solve this?!😯

Actually, this can be solved in many ways:
 
- Store the event property we need

```js
function handelArrowBtn(event) {
  let keyCode = event.keyCode
  if (keyCode === 40) {
    setCounter(counter - 1)
  } else if (keyCode === 38) {
    setCounter(counter + 1)
  }
}
```

or we may also pass the properties we want as arguments to the event handler function instead of directly accessing it from the function

```js
return (
    <div>
      <input
        type="number"
        value={counter}
        onKeyDown={(e) => handelArrowBtn(e.keyCode)}
      />
    </div>
  )
```
- Using `event.persist()` which will remove the synthetic event from the pool, which enables us accessing the event object properties in our code

```js
function handelArrowBtn(event) {
   event.persist()
   if (event.keyCode === 40) { 
      setCount(count - 1)
    } else if (event.keyCode === 38) {
      setCount(count + 1)
    }
  }
```



Hope this helps and thanks for reading. If you have any questions or topics you want me to write about I will be happy to help❤️.