Skip to content

useScrollSpy: accept a RefObject<HTMLElement> for scrollHost, not just a resolved HTMLElement #9025

Closed

Description

@ryami333

What package has an issue

@mantine/hooks (v9.3.1) — useScrollSpy

Describe the feature

Currently scrollHost only accepts a resolved HTMLElement:

export interface UseScrollSpyOptions {
  /** Host element to attach scroll event listener, if not provided, `window` is used */
  scrollHost?: HTMLElement;
  // ...
}

The idiomatic way to obtain a DOM node in React is a ref (useRef / callback ref). But a ref's .current isn't populated on first render and mutating it doesn't trigger a re-render, so passing scrollHostRef.current to the hook gives undefined on mount and the hook never re-initializes when the node attaches.

The current workaround is to convert the element into state via a callback ref, purely so the hook re-runs once the host exists:

const [scrollHost, setScrollHost] = useState<HTMLElement | null>(null);

useScrollSpy({ scrollHost: scrollHost ?? undefined, selector });

return <form ref={setScrollHost}>…</form>;

This works but is awkward boilerplate, especially when you already have a ref to that element for other purposes.

Proposed API

Let scrollHost accept either a resolved element or a ref object, with the hook resolving .current internally and re-initializing once it's available:

scrollHost?: HTMLElement | RefObject<HTMLElement | null>;

Usage would then collapse to the natural form:

const scrollHostRef = useRef<HTMLDivElement>(null);

useScrollSpy({ scrollHost: scrollHostRef, selector });

return <div ref={scrollHostRef}>…</div>;

This is backwards-compatible — existing HTMLElement callers are unaffected — and mirrors patterns elsewhere in Mantine where hooks accept refs.

Possible implementation

Internally, narrow the prop: if it's a ref ('current' in scrollHost), read .current; otherwise use it directly. The existing initialization useEffect already keys off scrollHost, so it would just need the resolved node in its dependency/closure.

Activity

  1. added
    Fixed in patchCompleted issues that will be published with next patch (1.0.X)
    on Jul 31, 2026
  2. rtivital commented on Aug 2, 2026

    @rtivital
    Member

    Added in 9.5.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fixed in patchCompleted issues that will be published with next patch (1.0.X)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions