Skip to content

React.js 19 nullable RefObject type is not supported #7549

Closed

Description

@clacladev

Provide a general summary of the issue here

In React 19 useRef and references in general have been refactored. Now they are stricter, they return null as potential value in their type.

useRef<HTMLDivElement>(null) will return:

  • RefObject<HTMLDivElement | null> in React 19
  • RefObject<HTMLDivElement> in React 18

A lot of React Aria hooks which accept a RefObject as input to create the component state, do not accept a nullable reference (RefObject<HTMLDivElement | null>).

For example

const calendarPopoverRef = useRef<HTMLDivElement>(null);
const { calendarProps } = useDatePicker<ZonedDateTime>(
    dateTimeInputProps,
    state,
    calendarPopoverRef, // <<< This will throw a Typescript error
);

🤔 Expected Behavior?

Hooks like useDatePicker should accept a RefObject<Element | null> type.
In general all packages should be checked against the TSC compiler.

😯 Current Behavior

It creates a TS error.

💁 Possible Solution

A temporary workaround is to add a cast to suppress the TS error. This is not a permanent solution though.

const calendarPopoverRef = useRef<HTMLDivElement>(null);
const { calendarProps } = useDatePicker<ZonedDateTime>(
    dateTimeInputProps,
    state,
    calendarPopoverRef as RefObject<Element>, // TODO: cleanup this type cast
);

🔦 Context

I am upgrading Nextjs 15.1 which also upgraded to stable React 19.

🖥️ Steps to Reproduce

  • Upgrade you examples to have react and @types/react to v19
  • Run npm tsc

Version

"@react-aria/datepicker": "^3.11.0"

What browsers are you seeing the problem on?

Chrome

If other, please specify.

No response

What operating system are you using?

macOS

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

Activity

  1. devongovett commented on Feb 28, 2025

    @devongovett
    Member

    I'm not seeing this issue. useDatePicker already does accept RefObject<Element | null>:

    export function useDatePicker<T extends DateValue>(props: AriaDatePickerProps<T>, state: DatePickerState, ref: RefObject<Element | null>): DatePickerAria {

    Here's a working example in the TS playground: Example

    Is this still an issue?

  2. msandula12 commented on Mar 4, 2025

    @msandula12

    I'm experiencing this as well while trying to upgrade to React 19, with useButton, useDialog, and useRangeCalendar, among others.

    const ref = useRef<HTMLButtonElement>(null);
    const { buttonProps } = useButton(props, ref);

    Argument of type 'RefObject<HTMLButtonElement | null>' is not assignable to parameter of type 'RefObject'.
    Type 'HTMLButtonElement | null' is not assignable to type 'Element'.
    Type 'null' is not assignable to type 'Element'.

  3. devongovett commented on Mar 4, 2025

    @devongovett
    Member

    Please provide a reproduction.

    Make sure you're using the latest version of React Aria too. React 19 compatibility was added in #6632, released in https://react-spectrum.adobe.com/releases/2024-07-22.html (see list of versions at the bottom). You may need to check your lock file in case something got pinned to an older version, or you have multiple versions installed.

  4. msandula12 commented on Mar 4, 2025

    @msandula12

    Please provide a reproduction.

    Make sure you're using the latest version of React Aria too. React 19 compatibility was added in #6632, released in https://react-spectrum.adobe.com/releases/2024-07-22.html (see list of versions at the bottom). You may need to check your lock file in case something got pinned to an older version, or you have multiple versions installed.

    Yep. Wasn't on latest version of React Aria. Should've checked that first. Updating fixed the issue. Thanks!

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions