Code Monkey home page Code Monkey logo

Comments (18)

josephsavona avatar josephsavona commented on July 19, 2024 3

@Maxou44 thanks for reporting this here! For folks working on react-hook-form, we've written up some guidelines for how to think about designing libraries for maximum compatibility with React, including React Compiler.

As @bluebill1049 notes, using useMemo with watch will cause results to be stale. This is part of a pattern, where non-hook APIs should always be memoizable. We cover this in reactwg/react-compiler#10 ("Any non-hook usage of your library should be memoize-able" section). Please let us know if you have questions!

from react-hook-form.

Gawdfrey avatar Gawdfrey commented on July 19, 2024 2

I guess "use no memo" can be used temporarily?
Currently trying to wrangler with Shadcn Form, RHF and the compiler. Looks like memoization in RHF is the main issue, not sure though

from react-hook-form.

mwskwong avatar mwskwong commented on July 19, 2024 2

@bluebill1049 @josephsavona So can I conclude that, at this stage, if we still want/need to use watch() with React Compiler enabled, there are two workarounds:

Option 1: replace watch() with useWatch()

  const { control, watch } = useForm();
- const field = watch('field');
+ const field = useWatch({ name: 'field', control })

Option 2: opt out of optimization with use no memo for components using watch()

  const Component = () => {
+   'use no memo'
    const { control, watch } = useForm();
    const field = watch('field');
  }

Is that correct?

from react-hook-form.

josephsavona avatar josephsavona commented on July 19, 2024 1

What I mean is that you can choose whether to apply React Compiler to the code that you publish.

Regardless, though, your users might wrap a call to watch() in a useMemo() (always allowed in React) or use React Compiler, which will do the equivalent of wrapping watch() calls in useMemo, and that will break their apps.

Note that useWatch is compatible w useMemo and React Compiler, so it seems like you should be able to deprecate watch in favor of useWatch. Unless there’s something I’m missing! This is all just a heads up so that you have context on potential issues your users may face using the library.

from react-hook-form.

bluebill1049 avatar bluebill1049 commented on July 19, 2024 1

thanks, @josephsavona makes sense. I will seek a solution if possible without deprecating watch. It's a great API for DX.

from react-hook-form.

Maxou44 avatar Maxou44 commented on July 19, 2024

Since React Compiler is still experimental, the bug have also been reported to React Compiler team, they replied it works as excepted and the library don't follow the React guidelines : facebook/react#29144

from react-hook-form.

A-Shleifman avatar A-Shleifman commented on July 19, 2024

The same applies to the formState.

export const useFieldError = () => {
  const { fieldKey } = use(SchemaFieldContext);
  const { errors } = useFormState({ name: fieldKey, exact: true });

  return get(errors, fieldKey)?.message?.toString();
};

This hook fails to subscribe to changes when React Compiler is enabled. I had to add use no memo for now.

from react-hook-form.

A-Shleifman avatar A-Shleifman commented on July 19, 2024

register sometimes works, but sometimes refuses to track changes. The register() call has to be called with use no memo to work reliably.

Another hack for now:

const useRegisterProps = (name: string, props: RegisterOptions = {}) => {
  'use no memo';

  return useFormContext().register(name, props);
};

from react-hook-form.

bluebill1049 avatar bluebill1049 commented on July 19, 2024
const { watch } = useForm({ defaultValues: { customerId: "", addressId: "" } });
const customerId = useMemo(() => watch("customerId"), [watch]);

watch reference is not going to change on each update unless we change the design (breaking change). almost need to remove this API just for the compiler. At this stage, consider using useWatch as a solution.

from react-hook-form.

bluebill1049 avatar bluebill1049 commented on July 19, 2024

thanks for the comment @josephsavona, is there a way we can flag the compiler to skip the memo within the library to avoid the potential breaking change?

from react-hook-form.

josephsavona avatar josephsavona commented on July 19, 2024

The challenge is that callers of the API would need to skip compilation. For your library itself you could just not compile the library - that’s your choice! But developers are going to expect that their libraries don’t block them from adopting the compiler on their own code.

Ultimately the watch API would need to either change (so that the form object itself changes when its state changes) or be replaced w the useWatch() API.

from react-hook-form.

bluebill1049 avatar bluebill1049 commented on July 19, 2024

For your library itself you could just not compile the library - that’s your choice!

Could you give some more details on this? We should probably do this before introducing breaking change.

from react-hook-form.

Maxou44 avatar Maxou44 commented on July 19, 2024

If we put the watch function in a useState, and update it each time a value is changed, it should work, no ?

from react-hook-form.

bluebill1049 avatar bluebill1049 commented on July 19, 2024

If we put the watch function in a useState, and update it each time a value is changed, it should work, no ?

return <div>{watch('test)}</div> should work just fine.

from react-hook-form.

nadeemc avatar nadeemc commented on July 19, 2024

@mwskwong For what it's worth, only useWatch seems to be working consistently from me.

from react-hook-form.

josephsavona avatar josephsavona commented on July 19, 2024

Yeah the most reliable option is useWatch().

from react-hook-form.

Maxou44 avatar Maxou44 commented on July 19, 2024

What's the plan to fix this directly in React Hook Form? How can I help?

from react-hook-form.

BrendanC23 avatar BrendanC23 commented on July 19, 2024

useWatch is nice because of the performance improvements (unrelated to the compiler). I switched from watch to useWatch and saw far fewer re-renders because useWatch re-renders only the individual component instead of re-rendering the form and all of its children.

from react-hook-form.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.