Why am I getting this problem?

By default, react-dropzone handles file uploads using its own internal state. But react-hook-form expects all form inputs (including file inputs) to be registered and controlled through its methods (register, setValue, watch, etc.).

If you connect them directly without syncing their states, the file input will not be submitted or validated correctly by react-hook-form.

Solution

You need to manually connect react-dropzone to react-hook-form using the setValue and watch methods. This way, when a file is dropped, you update the form state, and React Hook Form can track the file input properly.

Here’s how to integrate both libraries step-by-step using a beginner-friendly setup.

1. Install dependencies (if not already)

Install the required libraries to connect drag-and-drop with form handling.

npm install react-hook-form react-dropzone

2. Setup your form and integrate dropzone

This code connects react-dropzone with react-hook-form using setValue and watch for full file control.

// FileUploadForm.jsximport React from ‘react’;

import { useForm } from ‘react-hook-form’;

import { useDropzone } from ‘react-dropzone’;

 

function FileUploadForm() {

  const { register, handleSubmit, setValue, watch } = useForm();

  const uploadedFiles = watch(‘files’);

 

  const onDrop = (acceptedFiles) => {

    // Update form state manually

    setValue(‘files’, acceptedFiles, { shouldValidate: true });

  };

 

  const { getRootProps, getInputProps, isDragActive } = useDropzone({

    onDrop,

    multiple: true, // or false for single file

  });

 

  const onSubmit = (data) => {

    console.log(‘Form data:’, data);

  };

 

  return (

    <form onSubmit={handleSubmit(onSubmit)}>

      <div

        {…getRootProps()}

        style={{

          border: ‘2px dashed #aaa’,

          padding: ’20px’,

          textAlign: ‘center’,

          marginBottom: ’10px’,

        }}

      >

        <input {…getInputProps()} />

        {isDragActive ? (

          <p>Drop the files here …</p>

        ) : (

          <p>Drag ‘n’ drop some files here, or click to select files</p>

        )}

      </div>

 

      <ul>

        {uploadedFiles &&

          uploadedFiles.map((file, index) => (

            <li key={index}>{file.name}</li>

          ))}

      </ul>

 

      {/* Register the field with react-hook-form */}

      <input

        type=”hidden”

        {…register(‘files’, { required: ‘Please upload at least one file’ })}

      />

 

      <button type=”submit”>Submit</button>

    </form>

  );

}

 

export default FileUploadForm;

Also Read:

Code Breakdown

  • useDropzone handles drag and drop file logic.
  • onDrop triggers when files are dropped, where we use setValue to store files in the form.
  • watch(‘files’) tracks selected files for rendering.
  • A hidden input is registered to ensure react-hook-form knows about the files field.
  • You can apply validation rules just like any other field.

Key Takeaways

  • react-dropzone doesn’t integrate with react-hook-form out of the box.
  • Use setValue to sync dropped files with form state.
  • Use a hidden input with register to make it a valid form field.
  • Use watch to access the uploaded files reactively.