Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What are the plans for asChild and Slot with React.cloneElement be considered a legacy API method? #2537

Closed
djalmaaraujo opened this issue Nov 20, 2023 · 14 comments

Comments

@djalmaaraujo
Copy link

Question

We use Radix Primitives as the base for our components and asChild as a great benefit. Also, I imagine Slot uses cloneElement as the main implementation.

But, with cloneElement being considered a deprecated feature inside React, I wonder what plans are for supporting the same API with Radix Primitives.

Moving to context or using render props?

I did not post this into StackOverflow because it's an important discussion for the community.

Thank you!

Reference for cloneElement alternatives: https://react.dev/reference/react/cloneElement#passing-data-through-context.

@dzek69
Copy link

dzek69 commented Nov 22, 2023

I think you're mixing up "legacy" with "deprecated". One does not imply another and I see no information about cloneElement being deprecated. Do you have any source that actually claims that it is deprecated? I tried quick Googling with no luck.

@djalmaaraujo
Copy link
Author

Hello. Indeed, deprecated and legacy are different, but Legacy API are recommended to be avoided for any new code, which eventually will become discontinued.

"Legacy React APIs
These APIs are exported from the react package, but they are not recommended for use in newly written code"

So.. I still think the issue is valid to ask for the team if there are plans.

Reference: https://react.dev/reference/react/legacy

@novascreen
Copy link

novascreen commented Mar 16, 2024

I'm very much a fan of asChild, but I think render props could be quite useful, especially in the context of React Server Components.

Take the Collapsible.Trigger for example. Right now I either have to manage my own state, which means the parent component has to become a client component, or I use the data attributes for styling, which is somewhat limiting.

With a render prop we can get more control without having to make the parent a client component.

const CollapsibleDemo = () => {
  return (
    <Collapsible.Root className="CollapsibleRoot">
        <Collapsible.Trigger>
          {(getProps, context) => (
            <button {...getProps({ className: "IconButton" })}>
              {context.open ? <Cross2Icon /> : <RowSpacingIcon />}
            </button>
          )}
        </Collapsible.Trigger>

		{/* ... */}
    </Collapsible.Root>
  );
};

It's interesting how render props have gone kind of out of style with the rise of hooks, but it seems to me that RSCs might reverse that trend.

Edit: 🤦🏻‍♂️ I was wrong, this doesn't work, because a function can't be passed from an RSC to a client component, it's not serializable, only components can be passed as props.

@vladmoroz
Copy link
Contributor

No immediate plans, there are no equivalent workarounds at the moment and as of now asChild/Slot work great

@vladmoroz vladmoroz closed this as not planned Won't fix, can't repro, duplicate, stale Jun 4, 2024
@robinmind786
Copy link

Dear Team,

As we continue to develop and maintain our applications, it's important to adhere to modern best practices. Therefore, I would like to highlight that it is not advisable to use Legacy React APIs in our future projects. These APIs are deprecated and may be removed in future versions of React, which could lead to potential issues and increased maintenance effort.

By using the latest React APIs, we can ensure our codebase is more robust, maintainable, and aligned with the latest standards. This approach will also help us leverage new features and improvements, contributing to better performance and developer experience.

Let's prioritize updating any existing code that relies on Legacy APIs and focus on utilizing the current React API for all new development.

@dzek69
Copy link

dzek69 commented Jul 10, 2024

@djalmaaraujo @robinmind786

You both mentioned legacy APIs and how they are deprecated. But legacy isn't equal to deprecated. Some things in software are considered legacy forever and that's totally fine.

Do you have any source that says there are plans to deprecate cloneElement?

React docs lists legacy APIs and deprecated ones: https://react.dev/reference/react/legacy, cloneElement is not deprecated at the moment.

@robinmind786
Copy link

Screenshot_20240710-205400_Chrome.jpg

@dzek69
Copy link

dzek69 commented Jul 10, 2024

@robinmind786 we're not talking about createFactory here, but cloneElement

@amannn
Copy link

amannn commented Sep 29, 2024

@vladmoroz Could this pattern work as a replacement for cloneElement to be able to forward a ref?

It also has the benefit that asChild would work with a wrapped Server Component, I encountered this issue just recently (amannn/next-intl#1322).

@vladmoroz
Copy link
Contributor

@amannn do you have a minimal reproduction of your issue?

To my knowledge Slot and asChild worked fine with server components (Slot isn't a client component even), so I'd be interested to look into it.

@amannn
Copy link

amannn commented Sep 29, 2024

Just had a minute to set up a reproduction. What I noticed is that only async Server Components that are a child of an asChild parent are problematic.

Here's the reproduction: StackBlitz

Screenshot 2024-09-29 at 18 35 09

@amannn
Copy link

amannn commented Oct 2, 2024

Also when the child suspends due to usage of use(promise), the component completely vanishes and an error is shown: StackBlitz

Screenshot 2024-10-02 at 11 04 46

@vladmoroz Can we reopen this issue?

@vladmoroz
Copy link
Contributor

@amannn thanks for the repro, I think opening a separate issue about async components would make sense

@amannn
Copy link

amannn commented Oct 2, 2024

@vladmoroz Got it, here you go: #3165

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants