Control React Dropzone Uploader with React Hook Form
From the rubric of “write the blog post that you wish already existed,” I wanted to share a straightforward way of wrapping the React Dropzone Uploader component in a React Hook Form controller. And in the process, to explore each of these popular libraries a bit more in-depth. Let’s get straight to the solution by starting with the full CodeSandbox here:
Controller
React Hook Form claims to “embrace uncontrolled components.” That’s a bold statement. It hinges on the powerful <Controller />
component and the API that it provides. As always, I recommend starting with the documentation. In this case, we need to pay attention to the render
method and its properties:
onChange
,onBlur
,name
,ref
, andvalue
onChange
is a bit of a misnomer. I presume that it’s called onChange
so you could easily write onChange={(data) => onChange(data)}
. It also nicely shorthands to just onChange={onChange}
.
But it’s more of a setter. In the sense that you call it with the value that you want to pass from the controlled input. So if the user types something into an input field, you’d want to onChange
that value in order to set it to the named form data object. A more concrete example is when it’s combined with other handlers, like you can see on line 50 of src/App.tsx
. I’ve renamed it to setFiles
in the handler per my remark above. And that callback is called when the status of the files changes. Which brings us to…
setTimeout
At the time of this writing, there is a bug in React Dropzone Uploader where the callback handleChangeStatus
is called before the array of files is updated once a file is removed. A dirty fix to get around that is by using a no delay setTimeout
that takes an action on the next tick of the React lifecycle loop. When combined together with the React Hook Form controller, it correctly reacts to changes to the files
array, even when a file is removed.
Questions? Comments? Errors?
Feel free to reach out below or on Twitter if there’s anything I need to address.