Skip to content

Bug: useEffect() clears timeout immediately after a focus event with StrictMode #33008

Open
@layershifter

Description

@layershifter

React version: 18.3.1

Steps To Reproduce

  1. Navigate with keyboard to "toggle menu", press Enter
  2. Notice that a menu is opened, but a tooltip does not exist 🚨

Link to code example: https://stackblitz.com/edit/vitejs-vite-nnvwzvcm

The current behavior

2025-04-24.13.50.07.mp4
Menu:useEffect() // moves focus to MenuItem ✅ 
MenuItem:onFocus() => Tooltip:onFocus() // triggers a setTimeout() to open Tooltip ✅ 
Tooltip:useEffect:dispose() // calls clearTimeout() 🚨

The expected behavior

Without StrictMode a dispose function is not called:

2025-04-24.13.51.24.mp4

That's a simplified version of the issue from microsoft/fluentui#34296. I clearly understand that it's not a bug in React. It does what's expected 👍

The correct approach is to fire setTimeout() & clearTimeout() in useEffect(). The problem is that the described pattern is not unique and adopted by component libraries:

So we are wondering what is a proper solution in case and looking for guidance in this particular case 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions