react icon indicating copy to clipboard operation
react copied to clipboard

Bug: `onBlur` is not called when a focused element is unmounted

Open ling1726 opened this issue 3 years ago • 8 comments

React version: 18.2.0

Steps To Reproduce

  1. Go to https://codesandbox.io/s/adoring-flower-xk881j?file=/src/App.js
  2. Click on the button
  3. Notice that there is no console output when the button is unmounted

Link to code example: https://codesandbox.io/s/adoring-flower-xk881j?file=/src/App.js

The current behavior

When a focused element is unmounted onBlur is never called.

The expected behavior

Using vanilla HTML+JS when a focused DOM element is removed, the blur event is called. Here is the example: https://codesandbox.io/s/youthful-ptolemy-o8ulop?file=/src/index.js

ling1726 avatar Sep 06 '22 14:09 ling1726

It works if you downgrade to React 18.0, see https://github.com/facebook/react/issues/25095

rothsandro avatar Sep 15 '22 19:09 rothsandro

I think react is handling it like this. In your case you have removed the element from dom. and blur event get called only when we switch the focus to one element to another element.

devjs1000 avatar Oct 08 '22 09:10 devjs1000

In this case react does not detect the onBlur event because the focus of the component is not being removed, I think react cancels the events of the component when it is disassembled

jnadroj avatar Oct 12 '22 02:10 jnadroj

Our team ran into this bug today. We worked around it by shifting focus manually, but it would be helpful for React to trigger blur during unmount.

montlebalm avatar Jun 16 '23 15:06 montlebalm

you can easily achieve the desired output by triggering function which is present in onBlur before removing that element.

devjs1000 avatar Jun 21 '23 10:06 devjs1000

@devjs1000 can you explain how you would do it with an example, I can think of calling the onBlur in the cleanup of a useEffect but I'm not sure if it will work

jnadroj avatar Jun 21 '23 23:06 jnadroj

@devjs1000 can you explain how you would do it with an example, I can think of calling the onBlur in the cleanup of a useEffect but I'm not sure if it will work

Send me how you are using it I'll provide similar example then

devjs1000 avatar Jun 22 '23 12:06 devjs1000

You can find a workaround here

altyntsevlexus avatar Mar 11 '24 14:03 altyntsevlexus

You can use the following code to create a button that will disassemble when clicked. When disassembled, the Button component will execute the cleanup function, allowing you to perform any necessary action at that time.

import React, { useState, useEffect } from "react";

const Button = ({ onClick, onBlur, children }) => {
  const [mounted, setMounted] = useState(true);

  useEffect(() => {
    return () => {
      console.log("Button unmounted");
      // Here you can perform any necessary cleanup
    };
  }, []);

  return (
    <>
      {mounted && (
        <button onClick={onClick} onBlur={onBlur}>
          {children}
        </button>
      )}
    </>
  );
};

export default Button;

Regarding the use of the blur event, note that it is not triggered when the button is unmounted from the DOM. The onBlur event fires when an element loses focus, but in this case, when the button is unmounted, it no longer exists in the DOM and therefore cannot lose focus. Consequently, trying to use onBlur would be redundant and would have no effect.

jnadroj avatar Apr 09 '24 16:04 jnadroj

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

github-actions[bot] avatar Jul 08 '24 17:07 github-actions[bot]