フッターコンテンツにスキップ
ノードヘルプ

dropzone npm (開発者向けのしくみ)

ファイルアップロードはWebアプリケーションで一般的な機能であり、ユーザーフレンドリーにすることは良いユーザー体験にとって重要です。 このプロセスを簡素化する人気のライブラリの1つはDropzone.jsです。 When combined with React, Dropzone can be a powerful tool for implementing drag-and-drop file uploads. react-dropzoneは最小限の開発労力で完璧でシームレスに統合されます。 この記事では、Dropzone.jsライブラリの優れたラッパーであるreact-dropzoneパッケージを使用して、DropzoneをReactアプリケーションに統合する方法を案内します。

この記事では、PDFドキュメントを生成、編集、管理するためのIronPDF NPMパッケージも紹介します。

なぜReactでDropzoneを使用するのか?

Dropzoneは、ファイルアップロードをシームレスにするさまざまな機能を提供します:

1. ドラッグ&ドロップインターフェース

ユーザーがファイルをドラッグしてドロップすることでファイル選択を可能にし、プログラム的にファイルダイアログを追加します。

2. プレビュー

ドロップされたファイルのデフォルトのイメージサムネイルプレビューを表示し、UIの可読性を向上させます。

3. 複数ファイルのアップロード

一度に複数のファイルをアップロードすることをサポートします。

4. カスタマイズ可能

さまざまなオプションとコールバックが用意されており、高度にカスタマイズ可能です。 ファイルダイアログの開閉やファイル選択ダイアログをカスタマイズできます。

5. 大容量ファイルの分割アップロード

分割アップロードを使用して大容量ファイルをアップロードします。

6. イベントの処理

ファイルダイアログのキャンセルコールバックやブラウザのイメージリサイズイベントを処理できます。

Reactアプリケーションのセットアップ

Dropzoneを統合する前に、Reactアプリケーションがセットアップされていることを確認してください。まだ設定されていない場合は、Create React Appを使用して新しいReactプロジェクトを作成できます:

npx create-react-app dropzone-demo
cd dropzone-demo
npx create-react-app dropzone-demo
cd dropzone-demo
SHELL

react-dropzoneのインストール

ReactプロジェクトでDropzoneを使用するには、react-dropzoneパッケージをインストールする必要があります:

npm install react-dropzone
# or
yarn add react-dropzone
npm install react-dropzone
# or
yarn add react-dropzone
SHELL

react-dropzoneの基本的な使用法

ここにReactコンポーネントでのreact-dropzoneの使用例を示します:

import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';

// DropzoneComponent is a React component demonstrating basic usage of react-dropzone
const DropzoneComponent = () => {
  // Callback to handle file drops
  const onDrop = useCallback((acceptedFiles) => {
    console.log(acceptedFiles); // Log the accepted files
  }, []);

  // Extracted properties from useDropzone hook
  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()} style={dropzoneStyle}>
      <input {...getInputProps()} />
      {
        isDragActive ? 
          <p>Drop the files here ...</p> : 
          <p>Drag 'n' drop some files here, or click to select files</p>
      }
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';

// DropzoneComponent is a React component demonstrating basic usage of react-dropzone
const DropzoneComponent = () => {
  // Callback to handle file drops
  const onDrop = useCallback((acceptedFiles) => {
    console.log(acceptedFiles); // Log the accepted files
  }, []);

  // Extracted properties from useDropzone hook
  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()} style={dropzoneStyle}>
      <input {...getInputProps()} />
      {
        isDragActive ? 
          <p>Drop the files here ...</p> : 
          <p>Drag 'n' drop some files here, or click to select files</p>
      }
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
JAVASCRIPT

ファイルアップロードの処理

ファイルがドロップまたは選択されると、onDropコールバックで承認されたファイルの配列を受け取ります。 その後、サーバーにアップロードするなど、ファイルを処理できます。 fetchを使用してファイルをアップロードするために、onDropコールバックを拡張する方法は次のとおりです:

// onDrop callback to handle file uploads
const onDrop = useCallback((acceptedFiles) => {
  const formData = new FormData();
  // Append each file to the formData
  acceptedFiles.forEach((file) => {
    formData.append('files', file);
  });

  // Send a POST request to upload the files
  fetch('https://your-upload-endpoint', {
    method: 'POST',
    body: formData,
  })
  .then(response => response.json()) // Parse the JSON from the response
  .then(data => console.log(data)) // Log the response data
  .catch(error => console.error('Error:', error)); // Handle errors
}, []);
// onDrop callback to handle file uploads
const onDrop = useCallback((acceptedFiles) => {
  const formData = new FormData();
  // Append each file to the formData
  acceptedFiles.forEach((file) => {
    formData.append('files', file);
  });

  // Send a POST request to upload the files
  fetch('https://your-upload-endpoint', {
    method: 'POST',
    body: formData,
  })
  .then(response => response.json()) // Parse the JSON from the response
  .then(data => console.log(data)) // Log the response data
  .catch(error => console.error('Error:', error)); // Handle errors
}, []);
JAVASCRIPT

プレビューの表示

アップロードされたファイルのプレビューを表示することもできます。 これを行う方法の例は次のとおりです:

import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';

const DropzoneComponent = () => {
  const [files, setFiles] = useState([]);

  // onDrop callback to handle file drops and generate previews
  const onDrop = useCallback((acceptedFiles) => {
    setFiles(acceptedFiles.map(file => Object.assign(file, {
      preview: URL.createObjectURL(file)
    })));
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  // Generate thumbnails for each file
  const thumbs = files.map(file => (
    <div key={file.name}>
      <img
        src={file.preview}
        style={{ width: '100px', height: '100px' }}
        alt={file.name}
      />
    </div>
  ));

  return (
    <div>
      <div {...getRootProps()} style={dropzoneStyle}>
        <input {...getInputProps()} />
        {
          isDragActive ? 
            <p>Drop the files here ...</p> : 
            <p>Drag 'n' drop some files here, or click to select files</p>
        }
      </div>
      <div>
        {thumbs}
      </div>
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';

const DropzoneComponent = () => {
  const [files, setFiles] = useState([]);

  // onDrop callback to handle file drops and generate previews
  const onDrop = useCallback((acceptedFiles) => {
    setFiles(acceptedFiles.map(file => Object.assign(file, {
      preview: URL.createObjectURL(file)
    })));
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  // Generate thumbnails for each file
  const thumbs = files.map(file => (
    <div key={file.name}>
      <img
        src={file.preview}
        style={{ width: '100px', height: '100px' }}
        alt={file.name}
      />
    </div>
  ));

  return (
    <div>
      <div {...getRootProps()} style={dropzoneStyle}>
        <input {...getInputProps()} />
        {
          isDragActive ? 
            <p>Drop the files here ...</p> : 
            <p>Drag 'n' drop some files here, or click to select files</p>
        }
      </div>
      <div>
        {thumbs}
      </div>
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
JAVASCRIPT

クリーンアップ

メモリリークを回避するためにオブジェクトURLを解放することが重要です。 これをuseEffectフックを使用して達成できます:

import { useEffect } from 'react';

// useEffect to clean up object URLs to prevent memory leaks
useEffect(() => {
  // Revoke the data URIs
  return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
import { useEffect } from 'react';

// useEffect to clean up object URLs to prevent memory leaks
useEffect(() => {
  // Revoke the data URIs
  return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
JAVASCRIPT

IronPDFの紹介

IronPDFは、Node.jsアプリケーション内でのPDF生成を容易にする強力なnpmパッケージです。 It allows you to create PDF documents from HTML content, URLs, or even existing PDF files. 請求書、レポート、その他のドキュメントを生成する際に、IronPDFは直感的なAPIと堅牢な機能セットでプロセスを簡素化します。

IronPDFの主な機能

1. HTMLからPDFへの変換

HTMLコンテンツをPDFドキュメントに簡単に変換します。 この機能は、動的なPDFをウェブコンテンツから生成する際に特に便利です。

2. URLからPDFへの変換

URLから直接PDFを生成します。 これにより、Webページのコンテンツをキャプチャし、プログラム的にPDFファイルとして保存できます。

3. PDFの操作

既存のPDFドキュメントをマージ、分割、操作することが容易です。 IronPDFは、ページの追加、ドキュメントの分割など、PDFファイルを操作する機能を提供します。

4. PDFセキュリティ

パスワードやデジタル署名を使ってPDFドキュメントを保護できます。 IronPDFは、機密文書を不正アクセスから守るためのオプションを提供します。

5. 高品質な出力

テキスト、画像、フォーマットを正確にレンダリングする高品質なPDFドキュメントを作成します。 IronPDFは生成されたPDFがオリジナルコンテンツの忠実性を維持するようにします。

6. クロスプラットフォーム互換性

IronPDFはWindows、Linux、macOSなどのさまざまなプラットフォームに対応しており、幅広い開発環境に適しています。

7. 簡単な統合

IronPDFをnpmパッケージを使用してNode.jsアプリケーションに簡単に統合できます。 APIは十分に文書化されており、プロジェクトにPDF生成機能を組み込むことが容易です。

ウェブアプリケーション、サーバー側スクリプト、コマンドラインツールのいずれを構築していても、IronPDFはプロフェッショナル品質のPDFドキュメントを効率的かつ信頼性高く作成する力を提供します。

IronPDFを使用したPDFドキュメントの生成とDropzone NPMパッケージの使用

依存関係をインストール:まず、以下のコマンドを使用して新しいNext.jsプロジェクトを作成します(未作成の場合)。セットアップページを参照してください。

npx create-next-app@latest demo-dropzone-ironpdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
npx create-next-app@latest demo-dropzone-ironpdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
SHELL

次に、プロジェクトディレクトリに移動します:

cd demo-dropzone-ironpdf
cd demo-dropzone-ironpdf
SHELL

必要なパッケージをインストールします。

npm install @ironsoftware/ironpdf
npm install react-dropzone
npm install @ironsoftware/ironpdf
npm install react-dropzone
SHELL

PDFの作成:次に、IronPDFを使用してPDFを生成する簡単な例を作成しましょう。 Next.jsコンポーネント(例:pages/index.tsx)に以下のコードを追加します:

import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { useState } from "react";
import DropzoneComponent from "../components/mydropzone";

export default function Home() {
    const [textInput, setTextInput] = useState('');

    // Function to display different types of toast messages
    const notify = () => {
        toast.success("Success! This is a success message.", {
            position: "top-right"
        });
        toast.info("Information message", {
            position: "bottom-left"
        });
        toast.warn("Warning message", {
            autoClose: 5000
        });
        toast.error("Error message", {
            className: 'custom-toast',
            style: { background: 'red', color: 'white' }
        });
    };

    // Function to generate and download a PDF
    const generatePdf = async () => {
        try {
            const response = await fetch('/api/pdf?url=' + textInput);
            const blob = await response.blob();
            const url = window.URL.createObjectURL(new Blob([blob]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'awesomeIron.pdf');
            document.body.appendChild(link);
            link.click(); // Trigger the download
            link.parentNode.removeChild(link); // Remove the link
        } catch (error) {
            console.error('Error generating PDF:', error);
        }
    };

    // Handle changes in the text input field
    const handleChange = (event) => {
        setTextInput(event.target.value);
    }

    return (
        <div className={styles.container}>
            <Head>
                <title>Generate PDF Using IronPDF</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <main>
                <h1>Demo Drop Zone and Generate PDF Using IronPDF</h1>
                <DropzoneComponent />
                <p>
                    <span>Enter Url To Convert to PDF:</span>{" "}
                </p>
                <button style={{ margin: 20, padding: 5 }} onClick={generatePdf}>Generate PDF</button>
            </main>
            <style jsx>{`
                main {
                    padding: 5rem 0;
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                }
                footer {
                    width: 100%;
                    height: 100px;
                    border-top: 1px solid #eaeaea;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }
                footer img {
                    margin-left: 0.5rem;
                }
                footer a {
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    text-decoration: none;
                    color: inherit;
                }
                code {
                    background: #fafafa;
                    border-radius: 5px;
                    padding: 0.75rem;
                    font-size: 1.1rem;
                    font-family: Menlo,
                    Monaco,
                    Lucida Console,
                    Liberation Mono,
                    DejaVu Sans Mono,
                    Bitstream Vera Sans Mono,
                    Courier New,
                    monospace;
                }
            `}</style>
            <style jsx global>{`
                html,
                body {
                    padding: 0;
                    margin: 0;
                    font-family: -apple-system,
                    BlinkMacSystemFont,
                    Segoe UI,
                    Roboto,
                    Oxygen,
                    Ubuntu,
                    Cantarell,
                    Fira Sans,
                    Droid Sans,
                    Helvetica Neue,
                    sans-serif;
                }
                * {
                    box-sizing: border-box;
                }
            `}</style>
        </div>
    );
}
import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { useState } from "react";
import DropzoneComponent from "../components/mydropzone";

export default function Home() {
    const [textInput, setTextInput] = useState('');

    // Function to display different types of toast messages
    const notify = () => {
        toast.success("Success! This is a success message.", {
            position: "top-right"
        });
        toast.info("Information message", {
            position: "bottom-left"
        });
        toast.warn("Warning message", {
            autoClose: 5000
        });
        toast.error("Error message", {
            className: 'custom-toast',
            style: { background: 'red', color: 'white' }
        });
    };

    // Function to generate and download a PDF
    const generatePdf = async () => {
        try {
            const response = await fetch('/api/pdf?url=' + textInput);
            const blob = await response.blob();
            const url = window.URL.createObjectURL(new Blob([blob]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'awesomeIron.pdf');
            document.body.appendChild(link);
            link.click(); // Trigger the download
            link.parentNode.removeChild(link); // Remove the link
        } catch (error) {
            console.error('Error generating PDF:', error);
        }
    };

    // Handle changes in the text input field
    const handleChange = (event) => {
        setTextInput(event.target.value);
    }

    return (
        <div className={styles.container}>
            <Head>
                <title>Generate PDF Using IronPDF</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <main>
                <h1>Demo Drop Zone and Generate PDF Using IronPDF</h1>
                <DropzoneComponent />
                <p>
                    <span>Enter Url To Convert to PDF:</span>{" "}
                </p>
                <button style={{ margin: 20, padding: 5 }} onClick={generatePdf}>Generate PDF</button>
            </main>
            <style jsx>{`
                main {
                    padding: 5rem 0;
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                }
                footer {
                    width: 100%;
                    height: 100px;
                    border-top: 1px solid #eaeaea;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }
                footer img {
                    margin-left: 0.5rem;
                }
                footer a {
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    text-decoration: none;
                    color: inherit;
                }
                code {
                    background: #fafafa;
                    border-radius: 5px;
                    padding: 0.75rem;
                    font-size: 1.1rem;
                    font-family: Menlo,
                    Monaco,
                    Lucida Console,
                    Liberation Mono,
                    DejaVu Sans Mono,
                    Bitstream Vera Sans Mono,
                    Courier New,
                    monospace;
                }
            `}</style>
            <style jsx global>{`
                html,
                body {
                    padding: 0;
                    margin: 0;
                    font-family: -apple-system,
                    BlinkMacSystemFont,
                    Segoe UI,
                    Roboto,
                    Oxygen,
                    Ubuntu,
                    Cantarell,
                    Fira Sans,
                    Droid Sans,
                    Helvetica Neue,
                    sans-serif;
                }
                * {
                    box-sizing: border-box;
                }
            `}</style>
        </div>
    );
}
JAVASCRIPT

IronPDFはNodeのみで動作するため、次に、PDFがNodeで生成されるアプリのためのAPIを追加します。

ファイルpdf.jspages/apiフォルダに作成し、以下のソースコードを追加します:

// pages/api/pdf.js
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";

export default async function handler(req, res) {
    try {
        const url = req.query.url;
        const pdf = await PdfDocument.fromUrl(url);
        const data = await pdf.saveAsBuffer();
        console.log('PDF data:', data);

        res.setHeader('Content-Type', 'application/pdf');
        res.setHeader('Content-Disposition', 'attachment; filename=awesomeIron.pdf');
        res.send(data);
    } catch (error) {
        console.error('Error generating PDF:', error);
        res.status(500).end();
    }
}
// pages/api/pdf.js
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";

export default async function handler(req, res) {
    try {
        const url = req.query.url;
        const pdf = await PdfDocument.fromUrl(url);
        const data = await pdf.saveAsBuffer();
        console.log('PDF data:', data);

        res.setHeader('Content-Type', 'application/pdf');
        res.setHeader('Content-Disposition', 'attachment; filename=awesomeIron.pdf');
        res.send(data);
    } catch (error) {
        console.error('Error generating PDF:', error);
        res.status(500).end();
    }
}
JAVASCRIPT

注意: 上記のコードでは、必ず自分のライセンスキーを追加してください。

アプリを実行:Next.jsアプリを起動します:

npm run dev
# or
yarn dev
npm run dev
# or
yarn dev
SHELL

次に、ウェブサイトのURLを入力してPDFを生成し、「Generate PDF」をクリックします。 以下に示すように、awesomeIron.pdfという名前のファイルがダウンロードされます。

次にDropzoneをクリックして、ダウンロードしたファイルを選択します。これにより、ファイルのプレビューが表示され、下部に名前が表示されます:awesomeIron.pdf

IronPDFライセンス

ライセンスの詳細についてはIronPDFページを参照してください。

アプリにライセンスキーを以下のように配置してください:

import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
JAVASCRIPT

結論

Integrating Dropzone with React using react-dropzone is a straightforward process that significantly enhances the file upload experience. ドラッグ&ドロップ、ファイルプレビュー、広範なカスタマイズオプションなどの機能を備えたreact-dropzoneは、Reactプロジェクトに価値ある追加となり得ます。 その機能を探索し、アプリケーションのニーズに合わせてカスタマイズを始めましょう!

一方でIronPDFは、アプリケーションに簡単に統合可能な多機能なPDF生成および操作ライブラリです。 IronPDF offers thorough documentation and code examples to help developers to get started.

この記事で説明されている手順に従うことで、Reactアプリケーション内に堅実なファイルアップロードコンポーネントを作成し、最新のアプリケーション内にPDFファイル生成機能を統合することができます。

Darrius Serrant
フルスタックソフトウェアエンジニア(WebOps)

Darrius Serrantは、マイアミ大学でコンピュータサイエンスの学士号を取得し、Iron SoftwareでフルスタックWebOpsマーケティングエンジニアとして働いています。若い頃からコーディングに惹かれ、コンピューティングを神秘的かつアクセス可能なものとし、創造性と問題解決のための完璧な媒体と考えていました。

Iron Softwareでは、新しいものを創造することと、複雑なコンセプトをより理解しやすくすることを楽しんでいます。Resident Developerの一人として、次世代に専門知識を共有するために、学生を教えることにも志願しました。

Darriusにとって、その仕事は価値があり、実際の影響があるため、満足感があります。