Upload-Komponentenfunktion basierend auf React-Dropzone entwickeln (Beispieldemonstration)

Upload-Komponentenfunktion basierend auf React-Dropzone entwickeln (Beispieldemonstration)

Dieses Mal werde ich über die Fähigkeiten zur Entwicklung von Upload-Komponenten im React-Flask-Framework sprechen. Ich entwickle derzeit hauptsächlich Frontends mit React. Dabei habe ich viele interessante Frontend-UI-Frameworks kennengelernt – React-Bootstrap, Ant Design, Material UI, Bulma, usw. Es gibt viele beliebte Upload-Komponenten und die mit den meisten Benutzern sind jQuery-File-Upload und Dropzone, während zu den schnell wachsenden Neulingen Uppy und Filepond gehören.

Dieses Mal werde ich über die Fähigkeiten zur Entwicklung von Upload-Komponenten im React-Flask-Framework sprechen. Ich entwickle derzeit hauptsächlich Frontends mit React. Dabei habe ich viele interessante Frontend-UI-Frameworks kennengelernt – React-Bootstrap, Ant Design, Material UI, Bulma, usw. Es gibt viele beliebte Upload-Komponenten und die mit den meisten Benutzern sind jQuery-File-Upload und Dropzone, während zu den schnell wachsenden Neulingen Uppy und Filepond gehören. Es ist schade, dass der Autor von Fine-Uploader beschlossen hat, es nach 2018 nicht weiter zu pflegen. Als Nachzügler werde ich nicht nach dem Grund fragen, aber bitte respektieren Sie die Arbeit jedes Open-Source-Autors.

Hier wähle ich React-Dropzone aus folgenden Gründen:

  1. Entwickelt auf Basis von React, hochkompatibel
  2. Es wird online wärmstens empfohlen und sogar Material UI verwendet es zur Entwicklung von Upload-Komponenten.
  3. Der Schwerpunkt liegt hauptsächlich auf Drag & Drop , die Übertragungslogik kann jedoch vom Entwickler entworfen werden. Versuchen Sie beispielsweise, Socket-IO zum Übertragen von Dateiblöcken zu verwenden. Für den gesamten Knotenstapel ist dies wahrscheinlich machbar, aber ich verwende hier Flask und muss Blob in ArrayBuffer konvertieren. Aber ich habe nicht gelernt, wie man es in Python liest und schreibt.

Beispieldemonstration

1. Axios lädt normale Dateien hoch:

Einführung von react-dropzone durch yarn:

Garn hinzufügen React-Dropzone Axios

Das Front-End-JS ist wie folgt (falls etwas fehlt, ändern Sie es bitte selbst):

importiere React, { 
    verwendenState, 
    benutzeCallback,
    Effekt verwenden,
} von „reagieren“;
importiere {useDropzone} aus „react-dropzone“;
importiere "./dropzone.styles.css"
importiere InfiniteScroll von „react-infinite-scroller“;
importieren {
    Liste,
    Nachricht,
    // Benutzerbild,
    Drehen,
} von „antd“;
importiere Axios von „Axios“;

/**
* Dateigröße berechnen * @param {*} Bytes 
* @param {*} Dezimalstellen 
* @returns 
*/
Funktion formatBytes(Bytes, Dezimalstellen = 2) {
    wenn (Bytes === 0) returniere „0 Bytes“;

    konstant k = 1024;
    const dm = Dezimalstellen < 0? 0: Dezimalstellen;
    Konstantengrößen = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    const i = Math.floor(Math.log(bytes) / Math.log(k));

    returniere parseFloat((Bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + Größen[i];
}

/**
* Dropzone-Upload-Datei * @param {*} Eigenschaften 
* @returns 
*/
Funktion DropzoneUpload(Eigenschaften) {
    const [Dateien, setFiles] = useState([])
    const [wird geladen, wird gesetzt] = useState(false);
    const [hasMore, setHasMore] = useState(true);

    const onDrop = useCallback(akzeptierte Dateien => {
        setzeLaden(true);
        const formData = new FormData();
        smallFiles.forEach(Datei => {
            formData.append("Dateien", Datei);
        });
        axios({
            Methode: 'POST',
            URL: '/api/files/mehrereDateien',
            Daten: Formulardaten,
            Überschriften: {
                "Inhaltstyp": "multipart/Formulardaten",
            }
        })
        dann(bzw => {
            Dateien hinzufügen(akzeptierte Dateien);
            setzeLaden(false);
        });
    }, [Dateien]);

    // Dropzone-Einstellung
    const { getRootProps, getInputProps } = useDropzone({
        mehrere:wahr,
        beim Ablegen,
    });

    // Anhang löschen const removeFile = file => {
        const newFiles = [...Dateien]
        newFiles.splice(newFiles.indexOf(Datei), 1)
        setFiles(neueDateien)
    }

    useEffect(() => {
        // Uploader-Dateien initialisieren
        setFiles([])
    },[])

    zurückkehren (
        <Abschnitt Klassenname="Container">
        <div {...getRootProps({className: 'dropzone'})}>
            <input { ...getInputProps()} />
            <p>Ziehen Sie Dateien oder klicken Sie, um Dateien auszuwählen😊</p>
        </div>
        
        <div Klassenname="demo-unendlich-container">
            <UnendlicheScroll
                initialLoad={false}
                pageStart={0}
                loadMore={handleInfiniteOnLoad}
                hatMehr={!wird geladen && hatMehr}
                useWindow= {false}
            >
                <Liste
                    dataSource={Dateien}
                    renderItem={item=> (
                        <Liste.Element 
                            Aktionen={[
                                // <a key="list-loadmore-edit">Bearbeiten</a>, 
                                <a key="list-loadmore-delete" onClick={removeFile}>Löschen</a>
                            ]}
                            //extra={
                                
                            // }
                            Schlüssel={item.path}>
                            <Liste.Element.Meta 
                                avatar={
                                    <>
                                    {
                                        !!Artikeltyp && ['Bild/gif', 'Bild/jpeg', 'Bild/png'].includes(Artikeltyp) &&
                                        <Bild 
                                            Breite={100}
                                            alt='Logo'
                                            src={item.preview}
                                        />
                                    }
                                    </>
                                }
                                Titel={item.path}
                                Beschreibung={formatBytes(Artikelgröße)}
                            />
                        </Liste.Element>
                    )}
                >
                    {wird geladen && hat mehr && (
                        <div Klassenname="Demo-Ladecontainer">
                            <Drehen />
                        </div>
                    )}
                </Liste>
            </InfiniteScroll>
        </div>
        </Abschnitt>
    );
}

Flaschencode:

def mehrere Dateien():
wenn „Dateien“ nicht in request.files enthalten sind:
    return jsonify({'message': 'Keine Datei!'}), 200
Dateien = Anfrage.Dateien.getlist('Dateien')

für Datei in Dateien:
    if Datei:
        # Lösen Sie das chinesische Problem des sicheren Dateinamens durch Pinyin. Dateiname = sicherer Dateiname (''.join (lazy_pinyin (file.filename))
        Pfad(UPLOAD_FOLDER + '/' + file_info['dir_path']).mkdir(Eltern=True, exist_ok=True)
        file.speichern(os.path.join(UPLOAD_FOLDER + '/' + file_info['dir_path'], Dateiname))

return jsonify({'message': 'Erfolgreich gespeichert! !'})

2. Große Dateiimporte:

Generieren Sie Dateiblöcke mit der Methode file.slice(). Verwenden Sie Promise.all nicht, da dies zu nicht sequenziellen Anfragen und zur Beschädigung von Dateien führen kann.

js-Code:

const promiseArray = largeFiles.map(file => neues Promise((auflösen, ablehnen) => {
                        
    const chunkSize = CHUNK_SIZE;
    const chunks = Math.ceil(Dateigröße / Chunkgröße);
    lass chunk = 0;
    Lassen Sie chunkArray = neues Array();
    während (Block <= Blöcke) {
        let offset = chunk * chunkGröße;
        let slice = Datei.slice(Offset, Offset+Blockgröße)
        chunkArray.push([Scheibe, Versatz])
        ++Stück;
    }
    const chunkUploadPromises = (Schnitt, Offset) => {
        const largeFileData = neue FormData();
        largeFileData.append('largeFileData', Scheibe)
        returniere neues Promise((lösen, ablehnen) => {
            axios({
                Methode: 'POST',
                URL: '/api/files/largefile',
                Daten: largeFileData,
                Überschriften: {
                    "Inhaltstyp": "multipart/Formulardaten"
                }
            })
            .then(resp => {
                konsole.log(resp);
                auflösen (bzw.);
            })
            .catch(err => {
                ablehnen(fehler);
            })
        })
    };

    chunkArray.reduce( (vorheriges Versprechen, [nächsterChunk, nächsterOffset]) => {
        returniere vorherigesVersprechen.dann(() => {
            gibt chunkUploadPromises(nextChunk, nextOffset) zurück;
        });
    }, Versprechen.auflösen());
    lösen();
}))

Flaschencode:

Dateiname = sicherer_Dateiname(''.join(lazy_pinyin(Dateiname)))
Pfad(UPLOAD_FOLDER + '/' + file_info['dir_path']).mkdir(Eltern=True, exist_ok=True)
save_path = os.path.join(UPLOAD_FOLDER + '/' + file_info['dir_path'], Dateiname)
versuchen:
    mit open(save_path, 'ab') als f:
        f.seek(Versatz)
        f.schreiben(Datei.Stream.lesen())
        drucken("Zeit: " + str(datetime.now()) + " Offset: " + str(offset))
außer OSError:
    return jsonify({'Konnte nicht in Datei schreiben'}), 500

Abschluss

Die Dateiübertragung war für HTTP schon immer ein Problem, insbesondere die Übertragung großer Dateien. Am besten erstellen Sie selbst einen Client und übertragen die Daten über die Protokolle FTP und FTPS. Die zweite Methode ist zentralisiert und stammt von einem großen Unternehmen. Sie verwendet die Prüfsumme einer Datei, um zu ermitteln, ob sie hochgeladen wurde, und erzeugt so einen sofortigen Upload-Effekt. Die dritte Methode des dezentralisierten Bittorrent besteht darin, dass jeder Benutzer als Datei-Seed fungiert und beim Dateitransfer hilft. Diese Methode wird in China derzeit nicht häufig verwendet.

Dies ist das Ende dieses Artikels über die Entwicklung von Upload-Komponenten basierend auf React-Dropzone. Weitere relevante Inhalte zur Entwicklung von React-Dropzone-Komponenten finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Upload-Komponentenfunktion basierend auf React-Dropzone entwickeln (Beispieldemonstration)
  • Beispielcode für die Entwicklung einer H5-Formularseite basierend auf React-Hooks und der Konfiguration der Zarm-Komponentenbibliothek
  • React Native-Entwicklungspaket Toast und Laden Beispiel für das Laden einer Komponente
  • Detaillierte Erläuterung der Komponentenbibliotheksentwicklung mit React
  • React-Entwicklungstutorial: Kommunikation zwischen React-Komponenten
  • Detaillierte Erklärung zur Verwendung von require.ensure() zum bedarfsgesteuerten Laden von ES6-Komponenten in der React-Entwicklung
  • So verwenden Sie require.ensure zum Laden von Komponenten im ES6-Stil in der React-Entwicklung

<<:  Optimierung von Datentabellen in MySQL-Datenbanken, Analyse von Fremdschlüsseln und Nutzung von drei Paradigmen

>>:  So implementieren Sie Dual-Machine-Master und Backup mit Nginx+Keepalived

Artikel empfehlen

React implementiert Endlosschleifen-Scrollinformationen

In diesem Artikel wird der spezifische Code von R...

Implementierung der schnellen Projektkonstruktion von vue3.0+vant3.0

Inhaltsverzeichnis 1. Projektkonstruktion 2. Vue3...

setup+ref+reactive implementiert Vue3-Reaktionsfähigkeit

Das Setup wird zum Schreiben kombinierter APIs ve...

Spezifische Verwendung von useRef in React

Ich glaube, dass Leute, die Erfahrung mit React h...

Installieren Sie die virtuelle CentOS7-Maschine unter Win10

1. Laden Sie die VMware Workstation 64-Version he...

Interviewer stellen häufig Fragen zum Lebenszyklus von React

React-Lebenszyklus Zwei Bilder zum besseren Verst...

js und jquery, um einen Tab-Statusleisten-Umschalteffekt zu erzielen

Heute werden wir einen einfachen Fall durchgehen ...

Ein kurzer Vortrag über Rx-responsive Programmierung

Inhaltsverzeichnis 1. Beobachtbar 2. Funktionen h...