I have a custom component built using chakraUI which I want to use as a file input for react-hook forms.
Im using chakraUI to call click event on hidden html to select files.
When using this component, I noticed react-hook-form cannot get the file value from the html embedded.
<Controller
name={name}
control={control}
defaultValue=""
render={({ onChange, name, value }) => {
return (
<InputGroup>
<InputLeftElement pointerEvents="none">
<Icon as={FiFile} />
</InputLeftElement>
<input
name={name}
type="file"
onChange={ (e) => onChange(e.target.files[0]) }
accept={acceptedFileTypes}
//ref={inputRef}
//ref={ (el)=> { register(el) ; inputRef.current=el;}}
ref={(event) => {
register(event, name);
inputRef.current = event;
}}
style={{ display: "none" }}
/>
<Input
placeholder={placeholder || "Your file ..."}
onClick={() => inputRef.current.click()}
// onChange={(e) => {}}
// onChange={console.log(value)}
readOnly={true}
value={(value && value.name) || ""}
/>
</InputGroup>
);
}}
/>
The component is exported from a file and implemented as :
import React, { useState, useRef } from "react";
import {
Button,
ButtonGroup
} from "@chakra-ui/react";
import { useController, useForm, Controller } from "react-hook-form";
import UploadUnit from "./UploadUnit";
import updateAction from "./updateAction";
import storage from "./fireBaseConfig.js"
export const FileUpload = ({
name,
}) => {
const inputRef = useRef();
const { register,handleSubmit,errors,getValues,setValue,watch,control,ref } = useForm();
const onSubmit = (data) => {
console.log("List:" + data.testing[0].name ); // this correctly returns file name
console.log("List:" + data.trn[0].name ); // this returns undefined
const storageRef = storage;
//const fileRef = storageRef.child( data.files[0].name );
//fileRef.put(data.files[0]).then( () => { console.log("uploaded a file") })
};
register( { name: "trn", type:"custom"})
return (
<>
<form onSubmit={ handleSubmit(onSubmit) }>
<br />
<div>
<input type="file" name="testing" ref={register} />
</div>
<br></br>
<div>
<UploadUnit name="trn" ></UploadUnit>
</div>
<br />
<br />
<div>
<UploadUnit name="nis" ></UploadUnit>
</div>
<br />
<br />
<div></div>
<br />
<br></br>
<ButtonGroup spacing={4}>
<Button loadingText="Submitting" type="submit">
Save Progress
</Button>
<Button variant="outline">
Next
</Button>
</ButtonGroup>
</form>
</>
);
};
export default FileUpload;
I have tried :
ref={(event) => {
register(event, name);
inputRef.current = event;
}}
However when I try the above solution I get the following errors after I select file:
Uncaught TypeError: Failed to set the 'files' property on 'HTMLInputElement': Failed to convert value to 'FileList'
and:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'name')