Need help with react-dropzone?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

react-dropzone
7.7K Stars 664 Forks MIT License 544 Commits 10 Opened issues

Description

Simple HTML5 drag-drop zone with React.js.

Services available

!
?

Need anything else?

Contributors list

react-dropzone logo

react-dropzone

npm GitHub Workflow Status codecov Open Collective Open Collective Gitpod Ready-to-Code

Simple React hook to create a HTML5-compliant drag'n'drop zone for files.

Documentation and examples at https://react-dropzone.js.org. Source code at https://github.com/react-dropzone/react-dropzone/.

Installation

Install it from npm and include it in your React build process (using Webpack, Browserify, etc).

npm install --save react-dropzone

or:

bash
yarn add react-dropzone

Usage

You can either use the hook:

```jsx static import React, {useCallback} from 'react' import {useDropzone} from 'react-dropzone'

function MyDropzone() { const onDrop = useCallback(acceptedFiles => { // Do something with the files }, []) const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop})

return (

{ isDragActive ?

Drop the files here ...

:

Drag 'n' drop some files here, or click to select files

}
) } ```

IMPORTANT: Under the hood, this lib makes use of hooks, therefore, using it requires React

>= 16.8
.

Or the wrapper component for the hook: ```jsx static import React from 'react' import Dropzone from 'react-dropzone'

console.log(acceptedFiles)}> {({getRootProps, getInputProps}) => (

Drag 'n' drop some files here, or click to select files

)} ```

Warning: On most recent browsers versions, the files given by

onDrop
won't have properties
path
or
fullPath
, see this SO question and this issue.

Furthermore, if you want to access file contents you have to use the FileReader API:

```jsx static import React, {useCallback} from 'react' import {useDropzone} from 'react-dropzone'

function MyDropzone() { const onDrop = useCallback((acceptedFiles) => { acceptedFiles.forEach((file) => { const reader = new FileReader()

  reader.onabort = () => console.log('file reading was aborted')
  reader.onerror = () => console.log('file reading has failed')
  reader.onload = () => {
  // Do whatever you want with the file contents
    const binaryStr = reader.result
    console.log(binaryStr)
  }
  reader.readAsArrayBuffer(file)
})

}, []) const {getRootProps, getInputProps} = useDropzone({onDrop})

return (

Drag 'n' drop some files here, or click to select files

) } ```

Dropzone Props Getters

The dropzone property getters are just two functions that return objects with properties which you need to use to create the drag 'n' drop zone. The root properties can be applied to whatever element you want, whereas the input properties must be applied to an

:
```jsx static
import React from 'react'
import {useDropzone} from 'react-dropzone'

function MyDropzone() { const {getRootProps, getInputProps} = useDropzone()

return (

Drag 'n' drop some files here, or click to select files

) } ```

Note that whatever other props you want to add to the element where the props from

getRootProps()
are set, you should always pass them through that function rather than applying them on the element itself. This is in order to avoid your props being overridden (or overriding the props returned by
getRootProps()
):
jsx static
console.log(event) })} />

In the example above, the provided

{onClick}
handler will be invoked before the internal one, therefore, internal callbacks can be prevented by simply using stopPropagation. See Events for more examples.

Important: if you ommit rendering an

 and/or binding the props from 
getInputProps()
, opening a file dialog will not be possible.

Refs

Both

getRootProps
and
getInputProps
accept a custom
refKey
(defaults to
ref
) as one of the attributes passed down in the parameter.

This can be useful when the element you're trying to apply the props from either one of those fns does not expose a reference to the element, e.g.:

```jsx static import React from 'react' import {useDropzone} from 'react-dropzone' // NOTE: After v4.0.0, styled components exposes a ref using forwardRef, // therefore, no need for using innerRef as refKey import styled from 'styled-components'

const StyledDiv = styled.div

  // Some styling here
function Example() { const {getRootProps, getInputProps} = useDropzone()

Drag 'n' drop some files here, or click to select files

} ```

If you're working with Material UI and would like to apply the root props on some component that does not expose a ref, use RootRef:

```jsx static import React from 'react' import {useDropzone} from 'react-dropzone' import RootRef from '@material-ui/core/RootRef'

function PaperDropzone() { const {getRootProps, getInputProps} = useDropzone() const {ref, ...rootProps} = getRootProps()

Drag 'n' drop some files here, or click to select files

} ```

Important: do not set the

ref
prop on the elements where
getRootProps()
/
getInputProps()
props are set, instead, get the refs from the hook itself:

```jsx static import React from 'react' import {useDropzone} from 'react-dropzone'

function Refs() { const { getRootProps, getInputProps, rootRef, // Ref to the

inputRef // Ref to the

  } = useDropzone()
  

Drag 'n' drop some files here, or click to select files

} ```

If you're using the

 component, though, you can set the 
ref
prop on the component itself which will expose the
{open}
prop that can be used to open the file dialog programmatically:

```jsx static import React, {createRef} from 'react' import Dropzone from 'react-dropzone'

const dropzoneRef = createRef()

{({getRootProps, getInputProps}) => (

Drag 'n' drop some files here, or click to select files

)}

dropzoneRef.open() ```

Testing

Important:

react-dropzone
makes some of its drag 'n' drop callbacks asynchronous to enable promise based
getFilesFromEvent()
functions. In order to test components that use this library, you may want to use the react-testing-library: ```js static import React from 'react' import Dropzone from 'react-dropzone' import { act, fireEvent, render, waitFor } from '@testing-library/react'

test('invoke onDragEnter when dragenter event occurs', async () => { const file = new File([ JSON.stringify({ping: true}) ], 'ping.json', { type: 'application/json' }) const data = mockData([file]) const onDragEnter = jest.fn()

const ui = ( {({ getRootProps, getInputProps }) => (

)} ) const { container, rerender } = render(ui) const dropzone = container.querySelector('div')

dispatchEvt(dropzone, 'dragenter', data) await flushPromises(rerender, ui)

expect(onDragEnter).toHaveBeenCalled() })

async function flushPromises(rerender, ui) { await act(() => waitFor(() => rerender(ui))) }

function dispatchEvt(node, type, data) { const event = new Event(type, { bubbles: true }) Object.assign(event, data) fireEvent(node, event) }

function mockData(files) { return { dataTransfer: { files, items: files.map(file => ({ kind: 'file', type: file.type, getAsFile: () => file })), types: ['Files'] } } } ```

Note: using Enzyme for testing is not supported at the moment, see #2011.

More examples for this can be found in

react-dropzone
s own test suites.

Need image editing?

React Dropzone integrates perfectly with Doka Image Editor, creating a modern image editing experience. Doka supports crop aspect ratios, resizing, rotating, cropping, annotating, filtering, and much more.

Checkout the integration example.

Supported Browsers

We use browserslist config to state the browser support for this lib, so check it out on browserslist.dev.

Support

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

License

MIT

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.