Having this modal which has some inputs which are validated with react-hook-form:
import { yupResolver } from '@hookform/resolvers/yup';
import { useForm } from 'react-hook-form';
import * as yup from 'yup';
import { Modal, Footer, Input, Textarea } from '../ui-components';
import { usePostData } from '../lib/hooks/use-post-data';
const schema = yup.object().shape({
input: yup.string(),
description: yup.string()
});
export interface MyModalProps {
open: boolean;
toggle: () => void;
}
export function MyModal({ open, toggle }: MyModalProps) {
const emptyInput = {
input: '',
description: ''
};
const { handleSubmit, reset, register } = useForm({
resolver: yupResolver(schema)
});
const { mutate: postDta } = usePostData();
const onAddSubmit = (data) => {
postSignalMapping(data);
toggle();
reset(emptyInput);
};
const onCancelModal = () => {
toggle();
reset(emptyInput);
};
return (
<Modal
title='my modal'
open={open}
onClose={toggle}
footer={<Footer onSubmit={handleSubmit(onAddSubmit)} onCancel={onCancelModal} />}
>
<div>
<Input inputId='input' label='input' {...register('input')} />
<Textarea label='description' {...register('description')} />
</div>
</Modal>
);
}
export default MyModal;
It works pretty well beside the reset part which must be done when the modal is closed, it has some bugs sometimes.
Is there a way to make it re-render after the modal is closed?
It seems you need to also provide default values to the useForm hook.
You will need to pass defaultValues to useForm in order to reset the Controller components' value.
When invoking reset({ value }) without supplying defaultValues via useForm, the library will replace defaultValues with a shallow clone value object which you provide (not deepClone).
// ❌ avoid the following with deep nested default values
const defaultValues = { object: { deepNest: { file: new File() } } };
useForm({ defaultValues });
reset(defaultValues); // share the same reference
// ✅ it's safer with the following, as we only doing shallow clone with defaultValues
useForm({ deepNest: { file: new File() } });
reset({ deepNest: { file: new File() } });
Use the spread syntax to create shallow copies of the emptyInput default values object.
export function MyModal({ open, toggle }: MyModalProps) {
const emptyInput = {
input: '',
description: ''
};
const { handleSubmit, reset, register } = useForm({
defaultValues: { ...emptyInput },
resolver: yupResolver(schema)
});
...
const onAddSubmit = (data) => {
postSignalMapping(data);
toggle();
reset({ ...emptyInput });
};
const onCancelModal = () => {
toggle();
reset({ ...emptyInput });
};
...
}