Skip to main content
เทคโนโลยี

ลากวางอัปโหลดไฟล์ด้วย react-dropzone

เอาล่ะ ต่อกันมาจากบทความก่อนหน้าที่เราได้พูดถึง Cloudinary กันไปแล้ว ได้มีการพูดเกริ่น ๆ ถึงเจ้า Dropzone กันไปแล้ว ในบทความนี้เราก็จะมาแนะนำเจ้า library ตัวนี้ที่จะทำให้ระบบอัปโหลดภาพของเรานั้นสุดเจ๋งกันขึ้นไปอีกขั้นด้วยการลากวางไฟล์เพื่ออัปโหลด ไม่ต้องพูดพร่ำทำเพลง เรามาเริ่มกันเลยดีกว่า

เขียนโดย
Thanawat Udchachon
Internship @ borntoDev

เริ่มต้นการใช้งาน

เจ้าตัว react-dropzone เนี่ย มันก็เป็น React hook ง่าย ๆ ตัวหนึ่งที่ใช้สำหรับการทำส่วนของการลากวางไฟล์ และเช่นเคยสำหรับการจะใช้ library อะไร เราก็ต้องทำการติดตั้งกันก่อน ซึ่งก็สามารถทำได้ด้วยคำสั่ง npm install react-dropzone

ส่วนตัวโค้ด เพื่อเป็นการไม่เสียเวลา เราก็จะเริ่มจากโค้ดที่เราได้ทำไปกันตั้งแต่บทความก่อนหน้านะครับ

import React, { useState } from 'react';
import Axios from 'axios';

export default function Upload() {
    Axios.defaults.withCredentials = true;
    const [imageFile, setImageFile] = useState('');

    const handleFileInputChange = (e) => {
        const file = e.target.files[0];
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onloadend = () => {
            setImageFile(reader.result);
        }
    }

    const handleSubmitFile = (e) => {
        e.preventDefault();
        if (!previewSource) return;
        Axios.put(`api url`, { data: imageFile});
    }

    return (
        <div>
            <form onSubmit={handleSubmitFile}>
                <input
                    type="file"
                    onChange={handleFileInputChange}
                />
                <button type="submit">
                    submit
                </button>
            </form >
        </div >
    )
}

ซึ่งก็เป็นโค้ดที่จะมีปุ่มเลือกไฟล์ แล้วก็ปุ่มอัปโหลดไฟล์นั้น หน้าตาปุ่มดังกล่าวก็ยังดูธรรมดา ๆ อย่างที่เห็น

 

นำ react-dropzone มาใช้กับโค้ดเดิมของเรา

ในส่วนของการนำ react-dropzone มาใช้มันก็มีอยู่ 2 วิธีตามเว็บไซต์ของ react-dropzone คือ เขียนแยกเป็นฟังก์ชัน กับ wrap เป็น component ไปเลย แต่ในที่นี้จะทำแบบแรกละกัน

โดยเมื่อนำโค้ดตัวอย่างจากบนเว็บไซต์มาใส่ในโค้ดของเรา แล้วก็ตกแต่งนิดหน่อยก็จะได้ออกมาหน้าตาตามนี้เลย

import React, { useState } from 'react';
import Axios from 'axios';

export default function Upload() {
    Axios.defaults.withCredentials = true;
    const [imageFile, setImageFile] = useState('');

    const onDrop = useCallback((acceptedFiles) => {
        handleFileInputChange(acceptedFiles[0]);
    }, []);
    const { getRootProps, getInputProps, isDragActive } = useDropzone({
        onDrop,
        accepts: "image/*",
        multiple: false,
    })

    const handleFileInputChange = (file) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onloadend = () => {
             setImageFile(reader.result);
        }
    }

    const handleSubmitFile = (e) => {
        e.preventDefault();
        if (!imageFile) return;
        Axios.put(`api url`, { data: imageFile});
    }

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

            <form onSubmit={handleSubmitFile}>
                <button type="submit">
                    submit
                </button>
            </form >
        </div >
    )
}

โอ้โห มันโซอีซี่ โดยภายใน onDrop เราก็จะใส่ function handleFileInputChange ที่เราเคยได้เขียนไว้เพื่อส่งข้อมูลไฟล์ที่เราลากมาวางไปที่ฟังก์ชันของเรา ส่วนใน useDropzone ตรงนี้เราได้เพิ่ม accepts: “image/*” เข้าไป ซึ่งเป็นการบอกว่าเราจะรับไฟล์ประเภทรูปภาพ และ multiple: false เพื่อบอกว่ามันอัปโหลดได้ทีละไฟล์ ส่วนใน handleFileInputChange เองก็มีการเปลี่ยนแปลงเล็กน้อย โดย prop ที่เรารับมาเราจะเปลี่ยนเป็น file โดยมันจะส่งตรงไปที่ reader.readAsDataURL ไปเลย แล้วก็ลบ const file = e.target.files[0]; ไปได้เลยเพราะไม่ต้องใช้แล้ว เนื่องจาก react-dropzone ได้จัดการให้เราเป็นที่เรียบร้อยแล้ว

ส่วน component ของเรา เราก็เอาโค้ดจากบนเว็บไซต์มาใส่เลยเช่นกัน แล้วก็ลบในส่วนของ input ไปได้เลย เนื่องจากเรามี react-dropzone มาแล้วเช่นกัน

โดยผลลัพธ์จากออกมาดังนี้

(หน้าตาตอนยังไม่ได้ลากไฟล์มา)

 

(หน้าตาตอนมีไฟล์ถูกลากมาบน)

 

ตกแต่งด้วย CSS

บนหน้าลากวางไฟล์ของเรามันอาจจะยังดูไม่สวยไม่ชัดเจนเท่าไร เรามาลองตกแต่งมันด้วย CSS กันดูหน่อยดีกว่า

.dropzone {
  height: 40vh;
  margin: 1rem;
  padding: 1rem;
  border: 2px dashed lightgrey;
  border-radius: 0.5rem;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  -webkit-transition: background-color 100ms linear;
  -ms-transition: background-color 100ms linear;
  transition: background-color 100ms linear;
}
.upload .active {
  background-color: whitesmoke;
  -webkit-transition: background-color 100ms linear;
  -ms-transition: background-color 100ms linear;
  transition: background-color 100ms linear;
}

โดย CSS ของเราก็จะมีเพียง 2 ส่วนคือ .dropzone คือหน้าตาของ drop ในเวลาปกติ และ .upload กับ .active คือหน้าตาของ dropzone เวลามีไฟล์ถูกลากมา

และในส่วนของ component เราก็จะเป็นการนำ css เหล่านั้นมาใช้ดังนี้

<div className="upload" >
           <div
               {...getRootProps()}
               className={`dropzone ${isDragActive ? "active" : null}`}
           >
               <input {...getInputProps()} />
               {
                   isDragActive ?
                       <p>Drop the files here ...</p> :
                       <p>Drag 'n' drop some files here, or click to select files</p>
               }
           </div>

           <form onSubmit={handleSubmitFile}>
               <button type="submit">
                   submit
               </button>
           </form >
       </div >

ผลลัพธ์ที่ได้

ผลลัพธ์ที่ได้

 

สรุปสุดท้ายสิ่งที่ผู้อ่านจะได้รับ

เป็นยังไงกันบ้างครับสำหรับการใช้งาน react-dropzone เรียกได้ว่าง่ายสุด ๆ ไปเลยใช่ไหมครับ แต่สำหรับใครที่ยังต้องการตั้งค่าให้เหมาะกับงานของเรามากขึ้นเนี่ย มันยังมี PROPS กับ METHODS ให้ได้เล่นกันอีกมากมายเลย แล้วก็มีตัวอย่างแสดงวิธีการใช้งานที่ง่ายสุด ๆ สำหรับรายละเอียดเพื่อน ๆ ก็สามารถเข้าไปที่เว็บไซต์ https://react-dropzone.js.org/#src ได้เลย

อ้างอิงจาก

  1.  Image Uploads to Cloudinary in React with Drag & Drop, สืบค้นเมื่อ 27 มกราคม 2565 จาก: https://www.youtube.com/watch?v=V8w7K1HdrFo&t=404s
  2. react-dropzone, สืบค้นเมื่อ 4 กุมภาพันธ์ 2565 จาก: https://react-dropzone.js.org

หากคุณสนใจพัฒนา สตาร์ทอัพ แอปพลิเคชัน
และ เทคโนโลยีของตัวเอง ?

อย่ารอช้า ! เรียนรู้ทักษะด้านดิจิทัลเพื่ออัพเกรดความสามารถของคุณ
เริ่มตั้งแต่พื้นฐาน พร้อมปฏิบัติจริงในรูปแบบหลักสูตรออนไลน์วันนี้

BorntoDev

Author BorntoDev

BorntoDev Co., Ltd.

More posts by BorntoDev

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

    ประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
    รายละเอียดคุกกี้

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า