1. Use fileRequiredValidator instead of required, react hooks form could get undefined when the form is dynamic render. Like our promotion form has many step, types..., conditional render content ``` tsx <ControlledImageFileInput rules={createRule({ validate: fileRequiredValidator, })} /> ``` 2. If previous step has set image file to form, you should separate it form fullform, because FileList has no setter, it only can be set by user. ``` tsx // MEMO: exclude `bannerImageFile` to prevent unnecessary FileList error // eslint-disable-next-line @typescript-eslint/no-unused-vars const {bannerImageFile, ...form} = fullForm; // Error: Cannot set property length of FileList which has only a getter ``` 3. If you call reset() on form with file, it could make your file disappear ```tsx // Already removed from CommonInfoForm.tsx // useMountEffect(() => { // reset(form); // // eslint-disable-next-line react-hooks/exhaustive-deps // }, [reset, fullForm]); ``` 4. If you unmount fileInputField, the value may disappear, use hidden instead of `condition && <Component />` ```tsx <AdModels device={device} models={device === Device.Desktop ? adSettingWeb : adSettingMobile} device={Device.Desktop} models={adSettingWeb} onRemoveModel={handleRemoveModel} hidden={device !== Device.Desktop} {...methods} /> <AdModels device={Device.Mobile} models={adSettingMobile} onRemoveModel={handleRemoveModel} hidden={device !== Device.Mobile} {...methods} /> ``` 5. You can print error on `components/promotion/form/index.tsx` ```tsx <Button onClick={() => { methods.trigger(); console.error(methods.formState.errors); }} variant="contained" color="default" disabled={loading}> <Trans>common_button.check_form</Trans> </Button> ```