Reactを利用して、ファイルをドラック&ドロップで読み込む機能の作成を行いたい。
そんなの時に役に react-dropzone というライブラリが役に立ちました。
アップデートも細かく行われているようで、TypeScriptでも扱え非常に魅力的でした。
React + TypeScriptを使用したときのコード例
const { getRootProps, getInputProps, isDragActive, acceptedFiles } = useDropzone({ onDrop })
const baseStyle = useMemo(
() => ({
border: '1px dotted #888',
}),
[]
)
const borderNormalStyle = useMemo(
() => ({
border: '1px dotted #888',
}),
[]
)
const borderDragStyle = useMemo(
() => ({
border: '1px solid #00f',
transition: 'border .5s ease-in-out',
}),
[]
)
const onDrop = useCallback((acceptedFiles: File[]) => {
acceptedFiles.forEach((file: Blob) => {
// FilePathが直接取得できないため、FileReaderで取得する
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = () => {
console.log(file.name)
}
reader.readAsDataURL(file)
})
}, [])
const style = useMemo(
() => ({ ...baseStyle, ...(isDragActive ? borderDragStyle : borderNormalStyle) }),
[baseStyle, borderDragStyle, borderNormalStyle, isDragActive]
)
const content = (
<div {...getRootProps({ style })}>
<input id="file" type="file" {...getInputProps()} />
<FormGroup>
<div>
<AssignmentIcon />
</div>
<div>ファイルをドラック&ドロップしてください。</div>
</FormGroup>
</div>
)
途中コメントで一文、「// FilePathが直接取得できないため、FileReaderで取得する」と記載しておりますが、
react-dropzone ではブラウザのセキュリティ上の理由から意図的フォルダパスを取得することができません。
そのため、パスを取得したい場合はFileReaderから取得するしかないのです。