Bug: `onBlur` is not called when a focused element is unmounted
React version: 18.2.0
Steps To Reproduce
- Go to https://codesandbox.io/s/adoring-flower-xk881j?file=/src/App.js
- Click on the button
- 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
It works if you downgrade to React 18.0, see https://github.com/facebook/react/issues/25095
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.
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
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.
you can easily achieve the desired output by triggering function which is present in onBlur before removing that element.
@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
@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
You can find a workaround here
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.
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!