react-hook-form's setValue method is not working if input is in material ui dialog

Sam picture Sam · Dec 30, 2019 · Viewed 24.3k times · Source

I tried to use react-hook-form to validate inputs. But I found that if the input is placed in Material UI's dialog component, react-hook-form's setValue is not working as expected, but it works when I remove Dialog component. I guess the reason is that the value is set before the component mounts, but still can't find out the solution.

The value will be retrieved from the server, so I can't use react-hook-form's defaultValues.

https://codesandbox.io/s/react-hook-form-material-ui-twbbw

I have tried to use useState to control the input value, but there is another problem. When clear the input, click submit button, and error message shows, the first letter I key in will not be displayed.

https://codesandbox.io/s/react-hook-form-material-ui-ve2en

Answer

Domino987 picture Domino987 · Dec 31, 2019

The problem is with the register function. You are registering the Textfield with register after the ref of the Textfield is called.

The useEffect is called to set the name to 123 with setValue after the initial render. If open is true, the dialog content is rendered after the useEffect. After the content is rendered, the ref with register is called and the default value of Textfield (here undefined) is set to be the value of name.

That is why the value of the Textfield is "" on show. You need to call setValue after the render and ref callback is called, so that the value persists.

You have two options to do that:

  1. Set the value async in the useEffect with an async delay (setTimeout or promise) after open changed. So if you add open to the useEffect dependecy array and set the value async, it works. Here is a Sandbox.
  2. Set the default value of either the Textfield or add the default value to the hook with useForm({defaultValues: {name: '123}}).