react-hook-form / documentation

📋 Official documentation
http://react-hook-form.com
MIT License
723 stars 1.03k forks source link

Improve `watch` to reflect overloads #1056

Closed honey32 closed 1 week ago

honey32 commented 6 months ago

relates to #1040

I tried to make description in https://react-hook-form.com/docs/useform/watch to reflect real overload of the function according to its JSDoc

I'm not sure about description, but I'm sure it would be better if organized like this, because it has two different usages, which, without explanation, may lead beginners to confusion.

I'm willing to make some additional edit if needed to make description more precise.

vercel[bot] commented 6 months ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-hook-form-website ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 21, 2024 7:47am
BrendanC23 commented 1 month ago

Does this address issue #1040? It's probably worth documenting the type parameter (which is an EventType). The documentation should also mention that calling setValue within the watch callback will trigger an infinite loop (which can be avoided by checking that type === "change" before setting the value).

Also, TypeScript gives this as the type for watch:

export type WatchObserver<TFieldValues extends FieldValues> = (value: DeepPartial<TFieldValues>, info: {
    name?: FieldPath<TFieldValues>;
    type?: EventType;
    values?: unknown;
}) => void;

What is info.values? It's typed as unknown, but contains the form values, just like value.


Slightly unrelated: Why is value typed as DeepPartial<TFieldValues>? In order to access any properties, I need to use optional chaining because everything might be undefined. Why not type it as TFieldValues instead, which is what getValues() returns?

Currently, I'm doing this to easily access nested properties:

useEffect(() => {
    const subscription = watch((value, { name, type }) => {
        const actualValues = getValues();
    });

    return () => subscription.unsubscribe();
}, [watch]);