Skip to content

[internal] Refactor: use class for hover hook state#3791

Merged
romgrk merged 8 commits intomui:masterfrom
romgrk:perf-hover-class-optimization
Feb 3, 2026
Merged

[internal] Refactor: use class for hover hook state#3791
romgrk merged 8 commits intomui:masterfrom
romgrk:perf-hover-class-optimization

Conversation

@romgrk
Copy link
Copy Markdown
Contributor

@romgrk romgrk commented Jan 19, 2026

New attempt of #3451

Refactor to use a class for hover hook state.

@romgrk romgrk added type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. internal Behind-the-scenes enhancement. Formerly called “core”. labels Jan 19, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jan 19, 2026

commit: 033bea5

@mui-bot
Copy link
Copy Markdown

mui-bot commented Jan 19, 2026

Bundle size report

Bundle Parsed size Gzip size
@base-ui/react 🔺+234B(+0.06%) ▼-13B(-0.01%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@netlify
Copy link
Copy Markdown

netlify Bot commented Jan 19, 2026

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 033bea5
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/698175bb6a4ba90008169a22
😎 Deploy Preview https://deploy-preview-3791--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jan 19, 2026

Greptile Summary

This PR refactors the hover interaction hooks to use a class-based approach instead of individual React refs, improving performance by reducing the number of ref objects created.

Key Changes:

  • Replaced multiple React.useRef objects with a single HoverInteraction class instance
  • Changed property access from .current to direct property access
  • Simplified dependency arrays in useCallback and useEffect by including the single instance instead of multiple individual refs
  • Used useRefWithInit to create the class instance, ensuring it's initialized once per component

Observations:

  • Property names retain the "Ref" suffix (e.g., pointerTypeRef, interactedInsideRef) even though they're no longer ref objects - this is a naming inconsistency but doesn't affect functionality
  • The refactoring maintains the shared state pattern where both reference and floating interaction hooks share the same HoverInteraction instance via the store's dataRef
  • All logic remains unchanged; this is purely a structural refactoring for performance optimization

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • This is a purely structural refactoring that converts React refs to class properties for performance optimization. The logic remains identical, and the changes follow established patterns in the codebase (similar to useTimeout's Timeout class). All property accesses are correctly updated from .current to direct access. The only minor issue is a naming inconsistency with retained "Ref" suffixes, which doesn't affect functionality.
  • No files require special attention

Important Files Changed

Filename Overview
packages/react/src/floating-ui-react/hooks/useHoverInteractionSharedState.ts Refactored from React refs to a HoverInteraction class, converting individual refs into class properties for better performance
packages/react/src/floating-ui-react/hooks/useHoverFloatingInteraction.ts Updated to use class instance properties instead of ref objects, simplified dependency arrays
packages/react/src/floating-ui-react/hooks/useHoverReferenceInteraction.ts Updated to use class instance properties instead of ref objects, simplified dependency arrays

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jan 20, 2026
# Conflicts:
#	packages/react/src/floating-ui-react/hooks/useHoverFloatingInteraction.ts
#	packages/react/src/floating-ui-react/hooks/useHoverReferenceInteraction.ts
@github-actions github-actions Bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jan 21, 2026
@romgrk romgrk requested a review from michaldudak January 26, 2026 21:37
romgrk and others added 2 commits January 26, 2026 16:37
Add dispose and disposeEffect methods to properly clean up
openChangeTimeout and restTimeout when components unmount.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
data.hoverInteractionState = instance;
}

useOnMount(data.hoverInteractionState.disposeEffect);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is correct. Since this runs on all components using useHoverInteractionSharedState, unmounting a single Trigger will reset the timers. The more correct way of handling this would be triggering the cleanup when the Root part unmounts, but this would require having another hook for the Root.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't that issue also apply to the already existing hook?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, indeed. Let's tackle it in a separate PR, then.

@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Feb 2, 2026
# Conflicts:
#	packages/react/src/floating-ui-react/hooks/useHoverInteractionSharedState.ts
@github-actions github-actions Bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Feb 3, 2026
@romgrk romgrk merged commit e10e1da into mui:master Feb 3, 2026
23 checks passed
@romgrk romgrk deleted the perf-hover-class-optimization branch February 3, 2026 04:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Behind-the-scenes enhancement. Formerly called “core”. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants