ui icon indicating copy to clipboard operation
ui copied to clipboard

[bug]: React 19 forwardRef warnings

Open RDIL opened this issue 1 year ago • 10 comments

Describe the bug

React 19 has deprecated forwardRef - that means that these components will need to be modified in order to stop the deprecation warnings. The replacement is just to pass ref as a prop.

Affected component/components

Almost all

How to reproduce

Use next.js canary and open browser console

Codesandbox/StackBlitz link

https://github.com/vercel/next.js

Logs

No response

System Info

N/A

Before submitting

  • [X] I've made research efforts and searched the documentation
  • [X] I've searched for existing issues

RDIL avatar Jun 02 '24 16:06 RDIL

Same error here :(

hawkdevelopers avatar Jun 03 '24 16:06 hawkdevelopers

I have the same error. When will this be fixed? I want to practice Nextjs 15 (rc) + shadcn ui !

pavelbe avatar Jun 03 '24 21:06 pavelbe

Radix needs to be React 19 ready first. Which is happening right now with https://github.com/radix-ui/primitives/pull/2934. Shadcn/ui will probably follow shortly after.

Thijs-Lambert avatar Jun 04 '24 13:06 Thijs-Lambert

This is fixed in the new release candidate versions – please upgrade to the latest rc’s

vladmoroz avatar Jun 10 '24 16:06 vladmoroz

Radix React 19 compatibility RC => https://github.com/radix-ui/primitives/pull/2934

New RC versions => https://github.com/radix-ui/primitives/commit/1910a8c91c5927e58b8fca3aeaa31411f32fee7c

CarlosZiegler avatar Jun 12 '24 18:06 CarlosZiegler

Does anyone know how to migrate my components while preserving my changes to them? using CLI again would overwrite them.

I tried using the codemod but that didn't fix the errors like using the radix-RC does.

ZeyadZewail avatar Jul 09 '24 09:07 ZeyadZewail

Does anyone know how to migrate my components while preserving my changes to them? using CLI again would overwrite them.

I tried using the codemod but that didn't fix the errors like using the radix-RC does.

@ZeyadZewail Refer to my PR (#4356) for examples of how I've updated all of the components. Here's a summary of how I approached these changes.

Steps to Migrate Your Components:

  1. Remove forwardRef: You no longer need to wrap your component with forwardRef.
  2. Use React.ComponentProps for Typing: Instead of manually defining the prop types, use React.ComponentProps to automatically include the ref and other props.
  3. Remove Redundant ref Prop: Since ref is now included in props, you don’t need to explicitly pass ref={ref}.

Example of Standard HTML component

Before:

const CardHeader = React.forwardRef<
  HTMLDivElement,
  React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
  <div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
));

After:

/**
 * Note: Replace "div" with the tag being returned (ie, "tr" for a table row)
 */
const CardHeader: React.FC<React.ComponentProps<"div">> = ({
  className,
  ...props
}) => (
  <div className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
);

Example of Radix component wrapper

Before:

/**
 * Note: instead of an HTML tag, this time you'll use the type 
 * defined in `React.ComponentPropsWithoutRef`
 */
const Checkbox = React.forwardRef<
  React.ElementRef<typeof CheckboxPrimitive.Root>,
  React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
>(({ className, ...props }, ref) => (
  <CheckboxPrimitive.Root ref={ref} className={cn(className)} {...props} />
));

After:

const Checkbox: React.FC<
  React.ComponentProps<typeof CheckboxPrimitive.Root>
> = ({ className, ...props }) => (
  <CheckboxPrimitive.Root className={cn(className)} {...props} />
);

[!Warning]
You should not remove the ref={ref} line from the ChartTooltipContent or ChartLegendContent components unless you have modified them to spread the props (ie, {...props}) on the same child element where ref={ref} would be. For these components, add ref to the deconstructed props and keep the ref={ref} line in. Refer to my changes here to see what I mean.

Helpful Links

aleciavogel avatar Jul 20 '24 23:07 aleciavogel

@CarlosZiegler will running pnpm add radix-ui/primitives@1910a8c be enough to use the navigation menu? Or are there any additional steps?

gavan-x avatar Sep 04 '24 05:09 gavan-x

I'm not 100% sure. I'll take a look tomorrow and see if I can figure it out.

On Tue, Sep 3, 2024, 11:14 p.m. gavan1 @.***> wrote:

@aleciavogel https://github.com/aleciavogel Thank you for those tips but I am still getting some errors. Could you advise on this particular example https://www.radix-ui.com/primitives/docs/components/navigation-menu? from radix-ui website?

@CarlosZiegler https://github.com/CarlosZiegler will running pnpm add @.*** be enough to use the navigation menu? Or are there any additional steps?

const ListItem = React.forwardRef(({ className, children, title, ...props }, forwardedRef) => (

  • {title}

    {children}

  • — Reply to this email directly, view it on GitHub https://github.com/shadcn-ui/ui/issues/3898#issuecomment-2327937163, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACZFREFQ3IARHP6OYNERU23ZU2JLTAVCNFSM6AAAAABIVGITU2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMRXHEZTOMJWGM . You are receiving this because you were mentioned.Message ID: @.***>

    aleciavogel avatar Sep 04 '24 05:09 aleciavogel

    @aleciavogel Thanks you! Could help clarify the following for the MenuMenu Component? No error on compile but tsx linter has the following issue with the <a>

    const ListItem: React.FC<React.ComponentProps<typeof NavigationMenu.Link>> =({className, children, title, ...props }) =>(
      <li>
        <NavigationMenu.Link asChild> 
          <a className={classNames('ListItemLink', className)} {...props} >
            <div className="ListItemHeading">{title}</div>
            <p className="ListItemText">{children}</p>
          </a>
        </NavigationMenu.Link>
      </li>
    );
    

    Screen Shot 2024-09-09 at 9 00 59 AM

    gavan-x avatar Sep 09 '24 00:09 gavan-x

    @aleciavogel thanks for the helpful intro into ComponentProps! Looks like the jsdoc for that type recommends using more specific ComponentPropsWithRef or ComponentPropsWithoutRef

    just thought I'd add!

    image

    uncvrd avatar Oct 18 '24 08:10 uncvrd

    @aleciavogel thanks for the helpful intro into ComponentProps! Looks like the jsdoc for that type recommends using more specific ComponentPropsWithRef or ComponentPropsWithoutRef

    just thought I'd add!

    image

    Thanks for this info! Just waking up and will take a look later today

    aleciavogel avatar Oct 18 '24 13:10 aleciavogel

    Just to check, theres no easy way to upgrade all my shadcn components right? I have to make these changes all manually? Theres no codemod or something to facilitate this?

    chukwumaokere avatar Jan 03 '25 20:01 chukwumaokere

    Hi. We're closing some old issues as outdated. If this is still relevant, leave a message, we'll reopen it. Thank you. Appreciate your contribution to the project - shadcn

    shadcn avatar Oct 06 '25 13:10 shadcn