react-hook-form-mui icon indicating copy to clipboard operation
react-hook-form-mui copied to clipboard

Compatibility with React Server Components

Open beverloo opened this issue 1 year ago • 3 comments

Duplicates

  • [X] I have searched the existing issues

Latest version

  • [X] I have tested the latest version

Current behavior 😯

React supports React Server Components, which are evaluated on the server rather than on the client. Because they are not sent to the browser, they cannot use interactive APIs such as createContext and useState. They're experimentally available in React 18, and will become stable in React 19, currently in release candidate.

The react-hook-form-mui components rely on such interactive APIs, but do not mark themselves as client code. Because of this, errors are seen when using one of the components directly in a React Server Component. For example, in a Next.js project:

[!WARNING] Error: (0 , {imported module [project]/nodemodules/next/dist/server/future/route-modules/app-page/vendored/rsc/react.js [app-rsc] (ecmascript)}.createContext) is not a function

Layering server and client components in this manner is generally fine, and it's worth adding that Material UI marked their components as client code for the same reason. (E.g. the first line in <TextField>.)

Expected behavior 🤔

It would be great for react-hook-form-mui to add the "use client" directive to the top of each exported component: https://react.dev/reference/rsc/use-client

I've verified with a local fork that this indeed resolves the issue. Because react-hook-form-mui distributes as a bundle, there's some debate on the best way to achieve this, and including something in react-shim.js may be an option.

Steps to reproduce 🕹

Steps:

  1. Have a React Server Component, e.g. in Next.js
  2. Use react-hook-form-mui directly, without proxying through a client component
  3. Observe the aforementioned error
import { FormContainer, TextFieldElement } from 'react-hook-form-mui';

export default async function MyPage() {
    return (
        <FormContainer>
            <TextFieldElement name="field" label="Example field" />
        </FormContainer>
    );
}

beverloo avatar Jun 21 '24 13:06 beverloo

@beverloo you can try to re-export all the third party UI components https://sentry.io/answers/client-component-use-state/

ntubrian avatar Jun 21 '24 16:06 ntubrian

Thank you! Yes, that's exactly how I've worked around it, but that shouldn't be necessary hence this issue :)

beverloo avatar Jun 21 '24 16:06 beverloo

does the addition of use client has any implication for people who don't use that feature? If not I am happy to review a PR. Does it need to be added to every component or is it enough inside of the index.ts file?

dohomi avatar Jun 22 '24 10:06 dohomi

For those encountering a similar problem with Vike, here is the suggested workaround: https://vike.dev/broken-npm-package

FlorianCassayre avatar Feb 23 '25 16:02 FlorianCassayre