I am using React with react-hook-form
and I'm trying to store every value user enters in localStorage
to persist form state. I know I can redefine onChange
handler library provides and add to actual handler storing its value, but I'm looking for solution, that allow to provide custom onChange
or onBlur
handler that I can provide to useHook
and it will trigger on any field changes. Something like this:
const App = () => {
const methods = useForm({
onChange: (allValues) => localStorage.setItem('form', allValues),
}
/* ... */
}
CodePudding user response:
I am not aware of anything to do this, but you can probably use something like this :
const { watch } = useForm();
const watchField1 = watch("field1");
const watchField2 = watch("field2");
const watchField3 = watch("field3");
useEffect(() => {
localStorage.setItem('form', {
field1: watchField1,
field2: watchField2,
field3: watchField3,
});
}, [watchField1, watchField2, watchField3]);
CodePudding user response:
@teehbow's answer got me thinking about watch not only exact field value by its name, but the whole form. Reffering to docs, if you don't pass field name to hook, you will get the object with all form values.
const name = useWatch('first-name') // watch and return only first name as string
const values = useWatch() // watch all the form fields and returns form values object
If you don't wrap your form with FormProvider
, then you also need to pass control
to your watch hook. If you do, you can use it as in example above.
As I already have a value that subscribed to form changes, I only need to create effect that depends on values. To prevent unnecessary render of parent form element, i put out storing values to new component that do nothing but it
function PersistWatch(): null {
const values = useWatch()
useEffect(() => {
localStorage.setItem('key', values)
}, [values])
return null
}
and put this component inside FormProvider
. And it works! Also it's possible to pass local storage key using props and it will make component reusable in different forms.