question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

getValues is empty or with default values on component unmount

See original GitHub issue

Hey! Thanks a lot for this amazing lib. That’s what i was waiting for since hooks were released 😃 I’ve easily migrated forms from redux-form and formik to react-hook-form but faced one issue. So I’ve spotted a bug or maybe that’s how it should work. I have few forms which have like 5-6 fields in common. You could type in one form, accidentally close, or decided to switch to other form - all values you’ve entered were saved and new form was initialized with that values. Before I’ve got in parent component which renders all these forms a useState to save form values

const [savedValues, saveValues] = React.useState({})

Forms are rendered in modals and when I was closing the modal I was calling saveValues in return function of useEffect. Next time opening the form, values from savedValues were spreaded into initialValues of form. In react-hook-form I’ve found out that when you do like this

React.useEffect(() => () => {
  console.log(getValues());
}. []);

it is returning an empy object or default values if set.

Here is a reproducible example

Expected behavior getValues should return the last values

Additional context I’ve checked the sources and it seems that unmount and cleaning order should be different https://github.com/react-hook-form/react-hook-form/blob/master/src/useForm.ts#L948 https://github.com/react-hook-form/react-hook-form/blob/master/src/useForm.ts#L647 https://github.com/react-hook-form/react-hook-form/blob/master/src/useForm.ts#L465

Found out an adhoc solution - watch needed fields and save everything in ref. When unmount - get values from ref. Not very optimized because it will rerender form on every keystroke of watched fields

https://codesandbox.io/s/react-hook-form-basic-48z70?fontsize=14

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:18 (7 by maintainers)

github_iconTop GitHub Comments

14reactions
Grimonescommented, Nov 12, 2019

My apologies for the confusion 😃 forgot to add closure in useEffect in my first post. Updated.

Unfortunately that’s not an option for me because I don’t have by designs an option for user to save form values. But I found a better solution rather than using watch and it doesn’t feel like an Adhoc, I guess 😃

So the idea is to put unmount useEffect before useForm. Because in hooks order matters, the first useEffect would run before react-hook-form would run his own unmount useEffect cleaning the values. But we need to save reference to the getValues.

That’s how it looks

const getValuesRef = React.useRef(null);

React.useEffect(() => () => {
  if (getValuesRef.current) {
    console.log(getValues.current());
  }
}, []);

const { register, handleSubmit, getValues } = useForm();

// Save getValues reference on each rerender
React.useEffect(() => {
  ref.current = getValues;
});

Here is a working codesandbox

I think it’ll be good if we can add this to examples or FAQ on website because it’s a valid and widely used usecase so other people can easily find it.

2reactions
klawingcocommented, Jun 2, 2021

Oh god I was dumbfounded since a normal effects works at development, but I got the exact Issue when in Production.

Thanks @Grimones , I got it working, though I wrote a small hooks to avoid duplication of codes.

Hereis the hook, usePersist

const usePostPersist = onFormUnMounting => {
  const getValuesRef = useRef(null)
  // Save RHF data when form is unmounted
  // Used to persist data
  useEffect(
    () => () => {
      const values = getValuesRef?.current && getValuesRef?.current()
      if (onFormUnMounting && values) {
        onFormUnMounting(values)
      }
    },
    []
  )
  const setGetValuesRef = getValues => {
    getValuesRef.current = getValues
  }
  return setGetValuesRef
}

Then I can just used it on any page that I need it like this

  const setGetValuesRef = usePersist(onFormUnMounting)
  const {
    register,
    handleSubmit,
    errors,
    control,
    reset,
    getValues,
  } = useForm({
    mode: 'onSubmit',
    resolver: yupResolver(mySchema),
    defaultValues: {},
  })
  useEffect(() => {
    setGetValuesRef(getValues)
  })

Then I can reuse this logic, without putting many codes that do similar.

Thanks a lot again

Read more comments on GitHub >

github_iconTop Results From Across the Web

First form values get lost if the input unmounts in react-hook-form
There is a parent component for the FirstForm and SecondForm. The issue is when I click to go to the next form the...
Read more >
useForm | React Hook Form - Simple React forms validation
The defaultValues prop is used to populate the entire form values. It supports both sync and async set form default values. You can...
Read more >
API Documentation - Simple React forms validation
You can set the input's default value with defaultValue/defaultChecked (read more ... unregister input after component unmount }, [register]) return ( <form ...
Read more >
React Hook Form - Reset form with default values and clear ...
All fields are required so to test it make any of them empty and click submit, then click reset to bring back the...
Read more >
JavaScript Data Grid: Cell Renderer - AG Grid
By default the grid will create the cell values using simple text. ... Cell Renderer Component. The interface for the cell renderer component...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found