react-dropzoneと反応してドラッグアンドドロップファイルのアップロードを作成する方法
序章
react-dropzone は、ファイルのドラッグアンドドロップを処理するためのHTML5準拠のReactコンポーネントです。
HTML5は、を使用したファイルのアップロードをサポートしています。 react-dropzone
は、ドロップゾーンのカスタマイズ、プレビューの表示、ファイルの種類と量の制限などの追加機能を提供します。
注: ReactではなくVueを使用している場合は、vue-dropzoneのチュートリアルを参照してください。
このチュートリアルでは、Reactプロジェクトにreact-dropzone
を追加する方法を学び、Reactプロジェクトが提供する機能のいくつかを探ります。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Node.jsのローカル開発環境。 Node.jsをインストールしてローカル開発環境を作成する方法に従ってください。
このチュートリアルは、ノードv15.3.0、npm
v7.4.0、react
v17.0.1、およびreact-dropzone
v11.2.4で検証されました。
ステップ1—プロジェクトの設定
create-react-app を使用してReactアプリを生成し、依存関係をインストールすることから始めます。
- npx create-react-app react-dropzone-example
新しいプロジェクトディレクトリに移動します。
- cd react-dropzone-example
react-dropzone
をインストールします。
- npm install react-dropzone@11.2.4
この時点で、react-dropzone
を使用した新しいReactプロジェクトがあります。
ステップ2—Dropzoneコンポーネントを追加する
react-dropzone
にはデフォルト設定があり、最小限の構成で追加できます。
少なくとも、ユーザーの混乱を制限するために、ドロップされたファイルといくつかの召喚テキストを処理するonDrop
プロパティが必要になります。
import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
function DropzoneComponent() {
const onDrop = useCallback(acceptedFiles => {
console.log(acceptedFiles);
}, []);
const {
getRootProps,
getInputProps
} = useDropzone({
onDrop
});
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<div>Drag and drop your images here.</div>
</div>
)
}
export default DropzoneComponent;
このコードは、アプリケーションにドラッグアンドドロップ機能を提供します。
注: react-dropzone
はファイルをドラッグアンドドロップするように設計されていますが、デフォルトではドロップゾーンへのクリックイベントを受け入れ、ファイル選択のダイアログを起動します。
コンポーネントをReactアプリケーションに追加します。
import DropzoneComponent from './DropzoneComponent';
function App() {
return (
<div className="App">
<DropzoneComponent />
</div>
);
}
export default App;
アプリケーションを実行し、Webブラウザーで観察します。 Drag and drop your images here
というテキストのdivが表示されます。
さまざまなファイルをReactDropzoneコンポーネントにドラッグアンドドロップしてみてください。 このコードは現在、console.log
を使用してファイルを表示しています。 アップロードされたファイルの情報には、name
、lastModified
、size
、type
が含まれます。
この時点で、デフォルト構成で動作するReactDropzoneコンポーネントがあります。 react-dropzone
ドキュメント追加の構成オプション。
ステップ3—Dropzoneコンポーネントのスタイリング
デフォルトでは、react-dropzone
にはスタイルがありません。 ドキュメントには、フレックスボックスと破線の境界線の組み合わせを使用して、ファイルをドラッグアンドドロップする領域をユーザーに示す一般的な外観のスタイルが記載されています。
react-dropzone
は、コンポーネントがアクティブに対話された場合(isDragActive
)、ファイルを受け入れた場合(isDragAccept
)、またはファイルを拒否した場合(isDragReject
)の小道具もサポートします。 。
DropzoneComponent
に再度アクセスし、isDragActive
、isDragAccept
、およびisDragReject
をJPEGおよびPNG画像ファイルタイプに適用する場合に使用するように変更します。
import React, { useCallback, useMemo } from 'react';
import { useDropzone } from 'react-dropzone';
const baseStyle = {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: '20px',
borderWidth: 2,
borderRadius: 2,
borderColor: '#eeeeee',
borderStyle: 'dashed',
backgroundColor: '#fafafa',
color: '#bdbdbd',
transition: 'border .3s ease-in-out'
};
const activeStyle = {
borderColor: '#2196f3'
};
const acceptStyle = {
borderColor: '#00e676'
};
const rejectStyle = {
borderColor: '#ff1744'
};
function DropzoneComponent(props) {
const onDrop = useCallback(acceptedFiles => {
console.log(acceptedFiles);
}, []);
const {
getRootProps,
getInputProps,
isDragActive,
isDragAccept,
isDragReject
} = useDropzone({
onDrop,
accept: 'image/jpeg, image/png'
});
const style = useMemo(() => ({
...baseStyle,
...(isDragActive ? activeStyle : {}),
...(isDragAccept ? acceptStyle : {}),
...(isDragReject ? rejectStyle : {})
}), [
isDragActive,
isDragReject,
isDragAccept
]);
return (
<div {...getRootProps({style})}>
<input {...getInputProps()} />
<div>Drag and drop your images here.</div>
</div>
)
}
export default DropzoneComponent;
このコードは次の結果を生成します。
承認と拒否のコンポーネントの外観を変更すると、ファイルが有効かどうかについてユーザーにフィードバックを提供するのに役立ちます。
ステップ4—画像プレビューを追加する
プレビューは、コンポーネントにドラッグアンドドロップされた画像のコピーです。 これは、ユーザーが選択した画像ファイルの内容を確認するための視覚的なフィードバックをユーザーに提供するのに役立ちます。
プレビューはバージョン7.0.0で削除されましたが、ドキュメントには、Object.assign()
とURL.createObjectURL()
の組み合わせでプレビューを読み直すための代替手段が記載されています。
DropzoneComponent
に再度アクセスし、preview
を使用するように変更します。
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useDropzone } from 'react-dropzone';
const baseStyle = {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: '20px',
borderWidth: 2,
borderRadius: 2,
borderColor: '#eeeeee',
borderStyle: 'dashed',
backgroundColor: '#fafafa',
color: '#bdbdbd',
transition: 'border .3s ease-in-out'
};
const activeStyle = {
borderColor: '#2196f3'
};
const acceptStyle = {
borderColor: '#00e676'
};
const rejectStyle = {
borderColor: '#ff1744'
};
function DropzoneComponent(props) {
const [files, setFiles] = useState([]);
const onDrop = useCallback(acceptedFiles => {
setFiles(acceptedFiles.map(file => Object.assign(file, {
preview: URL.createObjectURL(file)
})));
}, []);
const {
getRootProps,
getInputProps,
isDragActive,
isDragAccept,
isDragReject
} = useDropzone({
onDrop,
accept: 'image/jpeg, image/png'
});
const style = useMemo(() => ({
...baseStyle,
...(isDragActive ? activeStyle : {}),
...(isDragAccept ? acceptStyle : {}),
...(isDragReject ? rejectStyle : {})
}), [
isDragActive,
isDragReject,
isDragAccept
]);
const thumbs = files.map(file => (
<div key={file.name}>
<img
src={file.preview}
alt={file.name}
/>
</div>
));
// clean up
useEffect(() => () => {
files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
return (
<section>
<div {...getRootProps({style})}>
<input {...getInputProps()} />
<div>Drag and drop your images here.</div>
</div>
<aside>
{thumbs}
</aside>
</section>
)
}
export default DropzoneComponent;
注:メモリリークを回避するには、URL.revokeObjectURL(file.preview)
を呼び出して、プレビューが不必要に保存されないようにする必要があります。
これで、1つまたは複数のファイルがドロップされるたびに、ファイルが状態に追加され、プレビューが表示されます。
結論
このチュートリアルでは、react-dropzone
と、それをReactアプリケーションで使用して、ファイルのアップロードに高度なドラッグアンドドロップ機能を提供する方法を紹介しました。
Reactの詳細については、 React.js シリーズのコーディング方法をご覧になるか、Reactトピックページで演習やプログラミングプロジェクトを確認してください。