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

issue: Async Default Values Not Loaded When Promise Resolves Immediately/Quickly #10195

Closed
1 task done
PacoHuerta opened this issue Mar 28, 2023 · 3 comments
Closed
1 task done
Labels
enhancement New feature or request

Comments

@PacoHuerta
Copy link

Version Number

7.43.8

Codesandbox/Expo snack

https://codesandbox.io/s/useformstate-forked-21tel9?file=/src/App.js

Steps to reproduce

The error described in the issue title is apparent as soon as Code Sandbox loads. Upon loading the sandbox, it is apparent that the input field does not have the expected default value, and the value will never load automatically.

If setTimeout's timeout value is increased from 0 to 500 (or any other value higher than 0), then the form behaves as described in the "Expected Behavior" section.

This is an issue when using libraries that cache responses and thus immediately resolve the promises they return.

Note that, if one clicks the toggle button on the page twice (unmount and remount occurs), then "mark" shows up on the field.

The problem is with this code snippet, which is found within creatFormControl.js:

if (isFunction(_options.defaultValues)) {
    _options.defaultValues().then((values) => {
      reset(values, _options.resetOptions);
      _subjects.state.next({
        isLoading: false,
      });
    });
  }

createFormControl is invoked from within the useForm hook; however, createFormControl is invoked from the main body of useForm instead of being invoked from within an effect (useEffect). Since createFormControl causes side effects, it should be invoked from within an effect.

After cloning this repository, commenting out the above code snippet within createFormControl and recreating that snippet within useEffect inside the body of useForm, the issue was resolved.

Expected behaviour

Value "mark" should be present in input field without any manual action after form fully loads.

What browsers are you seeing the problem on?

No response

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@bluebill1049
Copy link
Member

Would you like to send us a PR on this issue?

@bluebill1049 bluebill1049 added the enhancement New feature or request label Mar 28, 2023
@langovoi
Copy link

I faced with the same problem today

@langovoi
Copy link

langovoi commented Mar 29, 2023

Since createFormControl causes side effects, it should be invoked from within an effect.

if createFormControl is invoked after render (because of useEffect), useForm initiate new render of parent component. So I am not sure it is right change.

Maybe replace of useSubscribe with React.useSyncExternalStore fix this problem, because it get value at render time also.

useSubscribe({
subject: control._subjects.state,
next: (
value: Partial<FormState<TFieldValues>> & { name?: InternalFieldName },
) => {
if (
shouldRenderFormState(
value,
control._proxyFormState,
control._updateFormState,
true,
)
) {
updateFormState({ ...control._formState });
}
},
});

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 29, 2023
kylemclean pushed a commit to kylemclean/react-hook-form that referenced this issue Feb 2, 2024
…ct-hook-form#10203)

* 🍄 close react-hook-form#10195 close async defaultValues not load

* save some bytes

* fix api contract

* pin pnpm to v7
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants