対象読者
- JavaScriptとWeb開発の基礎に理解がある方
- Reactを用いたJavaScriptアプリケーション開発の経験者
前提環境
筆者の検証環境は以下の通りです。
- macOS Monterey 12.2.1
- Node.js 16.14.0/npm 8.3.1
- React 17.0.2
- react-scripts 5.0.0
- react-dropzone 12.0.4
リッチなファイル選択UI
Webアプリケーションを作っていると、ファイル選択のUIを用意する機会は数多くあります。
- プロフィール用の画像をアップロードする
- 報告書の文書ファイルをアップロードする
- 設定ファイルをインポートする
古くから頻出だったUIだけあって、HTMLでも簡単に実装することができます(リスト1)。
<!-- 最小限の実装 --> <input type="file" /> <!-- ファイル形式を絞る --> <input type="file" accept="application/json" />
accept
属性を指定することで、ファイル形式を絞り込むこともできます。リスト1のJSONファイルのみに絞り込んだほうを実際に表示すると、図1のように見慣れたUIが現れます。
「ファイルを選択」のボタンをクリックすると、図2のようにJSONファイルのみが有効なファイル選択UIが表示されます。
さて、ここまでは標準の機能でサポートされていますが、近年では図3のように、ドラッグ&ドロップでファイルを選択するUIもよく見かけるようになりました。
WindowsのエクスプローラーやmacOSのFinderなどで既にフォルダを開いている場合は、新たにダイアログを開いて選択するよりも、開いているフォルダからファイルをドラッグ&ドロップしたほうが便利です。本記事では、こういったUIを実現するためのReact向けライブラリとして、react-dropzoneについて解説します。
react-dropzone
react-dropzoneは有志のOSSプロジェクトによって開発されている、ドラッグ&ドロップできるファイル選択UIを扱うためのライブラリです。
HTMLのドラッグ&ドロップ仕様を活用したジェスチャーの挙動と、input要素を連携させるのが主な責務です。インターフェースとしては、コンポーネントによる実装(<Dropzone>
)と、React Hooksによる実装(useDropzone()
)の2種類を持っています。おおむね同じことができるので、本記事ではHooks版を主に解説します。
基本的な使い方
react-dropzoneは外部プロジェクトへの依存も特にないので、インストールするだけで使えるようになります。
$ npm install react-dropzone
インストールが終わったら、まずは最小限の実装で動かしてみましょう(リスト3)。
export function MyDropzoneBasic() { // (2) const onDrop = useCallback((acceptedFiles) => { console.log(acceptedFiles); // (4) }, []); // 空配列を指定したのでonDropのインスタンスはコンポーネントの破棄まで更新されない const { getRootProps, getInputProps } = useDropzone({ onDrop }); // (1) return ( <div> <div {...getRootProps()}>{/* (3) */} <input {...getInputProps()} />{/* (3) */} <p> ファイルをここにドラッグアンドドロップするか、 クリックしてファイルを選択してください </p> </div> </div> ); }
(1)がライブラリの呼び出し部分です。(2)で作ったコールバックonDrop
を引数で登録しつつ、(3)でdiv要素やinput要素をカスタマイズするための関数、getRootProps
やgetInputProps
を戻り値として提供します。見た目は図5のようになります。
何もスタイルを当てていないので、クリックやドラッグ&ドロップができるのはテキスト部分のみです。実際にファイルをドラッグ&ドロップすると、(2)のコールバックにFile型の配列データが渡されます。(4)で出力したログは図6のようになります。
ファイル情報が表示されました。基本的な使い方は簡単ですね。