Skip to content

Bug: forwardRef provides an empty object as ref, causing can't define property "current" error. #26419

Closed

Description

@hansottowirtz

React version: 18.3.0-next-3ba7add60-20221201

Hard to reproduce.

In Next.js, in rare cases, and only after a fast refresh, the ref object when using forwardRef is simply {}.

This leads to the TypeError: can't define property "current": Object is not extensible error when used with useImperativeHandle.

function Parent() {
  const carouselRef = useRef<any>();

  return <Suspense><Carousel ref={carouselRef} /></Suspense>
}

const Carousel = forwardRef((props, ref) => {
  if (!('current' in ref)) { debugger; }
  const thing = use(aPromise);
  return ...;
});

Screenshot 2023-03-17 at 18 49 21

In updateImperativeHandle, the ref is already an empty object.

Screenshot 2023-03-17 at 19 13 13

I haven't investigated it further yet, the stacktraces are quite hard to follow.

Activity

  1. joaoromeira commented on Mar 28, 2023

    @joaoromeira

    You should try this approach (I think you want to use the ref to control the carousel)

    import { useEffect } from 'react';
    import { forwardRef, Suspense, useImperativeHandle, useRef } from 'react'
    
    
    type CarouselProps = any
    
    type CarouselHandle = {
      init: () => void
    }
    
    const Carousel  = forwardRef<CarouselHandle, CarouselProps>((props, ref) => {
      useImperativeHandle(ref, () => ({
       init: () => {
         alert('Init!')
       } 
      }))
    
      return <div>Carousel</div>
    });
    
    
    const Parent = () => {
      const carouselRef = useRef<CarouselHandle>(null);
      
      useEffect(() => {
        if(carouselRef.current)
          carouselRef.current.init()
      }, [carouselRef])
      return (
        <Suspense fallback={<div />}>
          <Carousel ref={carouselRef} />
        </Suspense>
      )
    }
    
    export default Parent
  2. eps1lon commented on Mar 29, 2023

    @eps1lon
    Collaborator

    Can you open this on the Next.js repo as well? They might have a better idea how to reduce this to a repro just using React.

  3. hansottowirtz commented on Mar 29, 2023

    @hansottowirtz
    ContributorAuthor

    @eps1lon I have created a failing test/reproduction in #26420, I'm waiting for some help over there.

  4. hansottowirtz commented on Apr 3, 2023

    @hansottowirtz
    ContributorAuthor

    Fixed by #26535

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

    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