React 2 دقيقة للقراءة 708 مشاهدات

كيفية تطبيق رفع الملفات مع شريط التقدم في React

ابنِ مكون رفع ملفات حديث مع دعم السحب والإفلات وتتبع التقدم في الوقت الفعلي.

File upload interface

المكوّن

import { useState, useCallback } from 'react';

export default function FileUpload({ onUpload }) {
    const [progress, setProgress] = useState(0);
    const [isDragging, setIsDragging] = useState(false);
    const [file, setFile] = useState(null);

    const handleDrop = useCallback((e) => {
        e.preventDefault();
        setIsDragging(false);

        const droppedFile = e.dataTransfer.files[0];
        if (droppedFile) {
            setFile(droppedFile);
            uploadFile(droppedFile);
        }
    }, []);

    const uploadFile = async (file) => {
        const formData = new FormData();
        formData.append('file', file);

        const xhr = new XMLHttpRequest();

        xhr.upload.onprogress = (e) => {
            if (e.lengthComputable) {
                const percent = Math.round((e.loaded / e.total) * 100);
                setProgress(percent);
            }
        };

        xhr.onload = () => {
            if (xhr.status === 200) {
                const response = JSON.parse(xhr.responseText);
                onUpload?.(response);
            }
            setProgress(0);
        };

        xhr.onerror = () => {
            alert('Upload failed');
            setProgress(0);
        };

        xhr.open('POST', '/api/upload');
        xhr.send(formData);
    };

    return (
        <div
            onDragOver={(e) => { e.preventDefault(); setIsDragging(true); }}
            onDragLeave={() => setIsDragging(false)}
            onDrop={handleDrop}
            className={`border-2 border-dashed rounded-lg p-8 text-center
                ${isDragging ? 'border-blue-500 bg-blue-50' : 'border-gray-300'}`}
        >
            <input
                type="file"
                onChange={(e) => {
                    const f = e.target.files[0];
                    if (f) { setFile(f); uploadFile(f); }
                }}
                className="hidden"
                id="file-input"
            />

            <label htmlFor="file-input" className="cursor-pointer">
                <p>Drag & drop or click to upload</p>
            </label>

            {progress > 0 && (
                <div className="mt-4">
                    <div className="bg-gray-200 rounded-full h-2">
                        <div
                            className="bg-blue-500 h-2 rounded-full transition-all"
                            style={{ width: `${progress}%` }}
                        />
                    </div>
                    <p className="mt-2">{progress}%</p>
                </div>
            )}
        </div>
    );
}

الخلفية بـ Laravel

public function upload(Request $request)
{
    $request->validate([
        'file' => 'required|file|max:10240', // 10MB
    ]);

    $path = $request->file('file')->store('uploads', 'public');

    return response()->json([
        'path' => $path,
        'url' => Storage::url($path),
    ]);
}
مشاركة هذه المقالة:
ES
كتبه

Edrees Salih

مهندس برمجيات متكامل يتمتع بخبرة 9 سنوات. شغوف ببناء حلول قابلة للتطوير ومشاركة المعرفة مع مجتمع المطورين.

عرض الملف الشخصي

التعليقات (0)

اترك تعليقًا

لن يتم نشر بريدك الإلكتروني.

لا توجد تعليقات بعد. كن أول من يشارك أفكاره!

مقالات ذات صلة

مقالات ذات صلة

هل تحتاج مساعدة في مشروعك؟

احجز استشارة مجانية لمدة 30 دقيقة لمناقشة تحدياتك التقنية واستكشاف الحلول معًا.