From 19fb53c8293beb9b1c6d710a71932706ee1e5d6c Mon Sep 17 00:00:00 2001 From: neopostmodern Date: Wed, 10 Aug 2022 17:04:22 +0200 Subject: [PATCH] fix(client): sync all forms when receiving prop (e.g. after mutation), fixes #160 - create shared hook `useSyncForm` --- client/src/renderer/components/LinkForm.tsx | 4 +++- client/src/renderer/components/TagForm.tsx | 4 +++- client/src/renderer/components/TextForm.tsx | 8 ++++---- client/src/renderer/hooks/useSyncForm.ts | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 client/src/renderer/hooks/useSyncForm.ts diff --git a/client/src/renderer/components/LinkForm.tsx b/client/src/renderer/components/LinkForm.tsx index e401f3c..aac7786 100644 --- a/client/src/renderer/components/LinkForm.tsx +++ b/client/src/renderer/components/LinkForm.tsx @@ -2,6 +2,7 @@ import { pick } from 'lodash'; import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { LinkQuery } from '../generated/graphql'; +import useSyncForm from '../hooks/useSyncForm'; import { isUrlValid } from '../utils/textHelpers'; import { OptionalReactComponent } from '../utils/types'; import useSaveOnUnmount from '../utils/useSaveOnUnmount'; @@ -51,8 +52,9 @@ const LinkForm: React.FC = ({ return { values: formValues, errors }; }, }); - const { watch, handleSubmit } = formProps; + const { watch, handleSubmit, reset } = formProps; + useSyncForm(reset, defaultValues, link); useSaveOnUnmount({ onSubmit, defaultValues }, formProps); return ( diff --git a/client/src/renderer/components/TagForm.tsx b/client/src/renderer/components/TagForm.tsx index c82db65..09823b3 100644 --- a/client/src/renderer/components/TagForm.tsx +++ b/client/src/renderer/components/TagForm.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { useForm } from 'react-hook-form'; import styled from 'styled-components'; import { TagsQuery } from '../generated/graphql'; +import useSyncForm from '../hooks/useSyncForm'; import colorTools from '../utils/colorTools'; import useSaveOnUnmount from '../utils/useSaveOnUnmount'; import { TextField } from './CommonStyles'; @@ -34,7 +35,7 @@ interface TagFormProps { const TagForm: React.FC = ({ tag, onSubmit }) => { const defaultValues = pick(tag, tagFormFields); - const { register, getValues, handleSubmit } = useForm({ + const { register, getValues, handleSubmit, reset } = useForm({ defaultValues, mode: 'onBlur', resolver: (formValues) => { @@ -44,6 +45,7 @@ const TagForm: React.FC = ({ tag, onSubmit }) => { }, }); + useSyncForm(reset, defaultValues, tag); useSaveOnUnmount({ onSubmit, defaultValues }, { getValues }); const { ref: registerRef, ...registerProps } = register('color'); diff --git a/client/src/renderer/components/TextForm.tsx b/client/src/renderer/components/TextForm.tsx index 079f63c..6e957aa 100644 --- a/client/src/renderer/components/TextForm.tsx +++ b/client/src/renderer/components/TextForm.tsx @@ -1,7 +1,8 @@ import { pick } from 'lodash'; -import React, { useEffect } from 'react'; +import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { NotesForListQuery } from '../generated/graphql'; +import useSyncForm from '../hooks/useSyncForm'; import { OptionalReactComponent } from '../utils/types'; import useSaveOnUnmount from '../utils/useSaveOnUnmount'; import { NameInput } from './formComponents'; @@ -39,9 +40,8 @@ const TextForm: React.FC = ({ }, }); const { register, reset, handleSubmit } = formProps; - useEffect(() => { - reset(defaultValues); - }, [reset, text]); + + useSyncForm(reset, defaultValues, text); useSaveOnUnmount({ onSubmit, defaultValues }, formProps); diff --git a/client/src/renderer/hooks/useSyncForm.ts b/client/src/renderer/hooks/useSyncForm.ts new file mode 100644 index 0000000..41ce9be --- /dev/null +++ b/client/src/renderer/hooks/useSyncForm.ts @@ -0,0 +1,15 @@ +import { useEffect } from 'react'; +import { UseFormReset } from 'react-hook-form'; + +const useSyncForm = ( + reset: UseFormReset, + defaultValues: FormType, + entityProp: EntityType +) => { + // observe changes of prop entity (because it stays identity-stable), but use picked value of defaultValues + useEffect(() => { + reset(defaultValues); + }, [reset, entityProp]); +}; + +export default useSyncForm;