Few weeks ago, I found myself desperately googling this question while I was trying to fix a React glitch. The answer is certainly, No! DOM is made to receive one user interaction event at a time, but I wanted to get rid of this error so badly and I was still hoping that there could be a way.

Let me clarify the case with a more elaborative example. I created a simple typeahead component which can be downloaded via https://github.com/SercanSercan/storksnest/tree/master/simple-typeahead

simple-typeahead-demo
Simple typeahead component demo

As the gif image above declares, there are two basic UI elements in a typical typeahead component: There should be a text box and a list of items that become visible upon user interaction. Component should also have some keyboard navigation where the glitch pops up.

Please take a look at the render part of the typeahead:

Screenshot 2020-05-24 at 18.40.08
Core render of typeahead component

Typeahead basically has the following DOM structure

  • div.typeahead => wrapper
    • input => textbox
    • ul => unordered list
      • li => list item to show a capital
      • li => list item to show a capital

As the code snippet above shows, when the user sets the focus on input, showSuggestions hook is set true. Hence, unordered list becomes visible. I did this by using onFocus and onBlur events. This is quite straightforward thinking. If the user tabs through my text box, dropdown will be shown to user and it will be hidden on the next tab. However, when the user clicks on a list item (to select a capital), onBlur got triggered although I wanted to trigger my onClick event on <li/>. Therefore, I quit using onClick event and used onMouseDown instead. Then, typeahead component worked like a charm 🙂 As a result, I couldn’t trigger two DOM events at the same time, but found a way to orchestrate related events. This should be the approach to solve such problems among UI events.

BONUS MATERIAL => Jøkul’s useKeyListener hookstorksnest_jøkul_bonus_useKeylistener_hook

Aforementioned application (simple-typeahead) can be inspiring for those who are about to develop their own dropdown component. At this point, I would like to introduce you a promising UI library called Jøkul. This library provides you stylish UI components (checkbox, datepicker, progressbar, etc. ) while creating your SPA. In my application, I benefited a custom hook from Jøkul. So, how to use Jøkul’s useKeyListener hook?

Step 1:

Install jkl-react-hooks on your web app:

npm i @fremtind/jkl-react-hooks

Step 2: 

Import useKeyListener under your target component:

import { useKeyListener } from '@fremtind/jkl-react-hooks';

Step 3: 

Identify the set of keys that you will use. In my case, I needed to use following list of keys:

const keys = ['ArrowUp', 'ArrowDown', 'Enter', 'Escape'];

Step 4: 

Create a reference for your input element:

const ref = useRef(null);
...
<input ref={ref} ...

Step 5:

Program it your way! As the code snippet below indicates, I created a function called onKeyPressed and sent it to Jøkul’s useKeyListener. Besides, my function consists of nothing but a switch case where I implement expected output. For example, if the user presses arrow down key, I increment the value of selectedIndex as long as it is within the length of my suggestions list.

Screenshot 2020-05-24 at 19.09.59

Jøkul’s useKeyListener stops you googling key codes and your source code becomes more readable and neat.

Sercan Leylek / OSLO

One thought on “Is it possible to trigger two DOM events at the same time on React?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s