The event listener click comes after blur in priority.

The event listener click comes after blur in priority.

·

2 min read

I just noticed that the onSubmit event of the form is not firing, because the onBlur event of the name input has priority.

When you have the mouse on the name input, and then you click directly on the submit button (without touching anything else before that),... the event that is firing first is the onBlur of the name input, not the onSubmit of the form, nor the onClick. Already tested it with onClick, onMouseDown and with onKeyPress,... always onBlur has priority.

And this is particularly bad, because the onSubmit never gets executed. When the onBlur event causes a re-render, submit is not even fired.

Why exactly? Because as here says:

All the events are fired in order of priority. The event listener click comes after blur in priority. This causes a blur to fire but not the click. By using setTimeout on the blur it delays the blur and allows for the click to take priority.

https://github.com/facebook/react/issues/4210

import React, { useState } from 'react'


const SimpleInput = (props) => {



  const [enteredName, setEnteredName] = useState('');
  const [enteredNameTouched, setEnteredNameTouched] = useState(false)

  const enteredNameIsValid = enteredName.trim() !== '';
  const nameInputIsInValid = !enteredNameIsValid && enteredNameTouched;






  const nameInputChangeHandler = event => {
    setEnteredName(event.target.value);
    console.log("3");
  }





  const nameInputBlurHandler = (event) => {
    setEnteredNameTouched(true);
    console.log("1");
  }





  const formSubmissionHandler = (event) => {
    event.preventDefault();
    setEnteredNameTouched(true);
    console.log("2");
    if (!enteredNameIsValid) {
      return;
    }

    setEnteredName('');
    setEnteredNameTouched(false);
  };




  const nameInputClasses = nameInputIsInValid ? 'form-control invalid' : 'form-control';



  return (

    <form onSubmit={formSubmissionHandler}>
      <div className={nameInputClasses}>
        <label htmlFor='name'>Your Name</label>
        <input
          value={enteredName}
          type='text'
          id='name'
          onChange={nameInputChangeHandler}
          onBlur={nameInputBlurHandler}
        />
        {nameInputIsInValid && <p className='error-text'>Name must not be empty</p>}
      </div>
      <div className="form-actions">
        <button>Submit</button>
      </div>
    </form>
  );
};



export default SimpleInput;

Screenshot (336).png