2017-11-27 1 views
0

Ich benutze React Dropzone (aber ich habe das gleiche Problem an vielen verschiedenen Orten). Dies ist eine Funktion in meiner Hauptkomponente:React + Redux - Warten auf Ende der Aktion?

onDrop(images) { 
    this.props.dispatch(setImages(images)); 

    this.props.images.forEach(file => { 
    const reader = new FileReader(); 
    reader.onload =() => // render images 
    reader.onerror =() => // display error 
    reader.readAsDataURL(file); 
    }); 
} 

Der Versand schiebt gerade Anordnung von Bildern auf den Zustand und dann map ich es Requisiten.

Leider nimmt Versand einige Zeit und this.props.images ist undefined im Beispiel oben, es funktioniert gut, wenn ich in einem Timeout von 2 Sekunden gesetzt oder so, aber es ist viel zu gefährlich.

Wie kann ich das beheben? Ich habe Versprechungen ausprobiert, aber ich weiß nicht, wer sie arbeiten, und ich habe das Gefühl, dass sie hauptsächlich für asynchrone Anfragen gedacht sind.

+0

Ich habe versucht, aber es hat nie funktioniert - ich Dispatching die aus meinen Komponenten und alle Beispiele I Were finden konnte, Ich benutze externe Objekte, die ich nicht brauche, weil sie mein Projekt viel zu komplex machen. – Wordpressor

+0

setImages ist 'sync', ich verschiebe nur Dateien in den Redux-Speicher, damit ich sie woanders verwenden kann (keine Sorge, sie sind wirklich klein). – Wordpressor

+0

@ Li357 Redux ''dispatch' würde' this.props' nicht synchron aktualisieren. 'this.props' würde beim nächsten Rendering der Komponente einen neuen Wert annehmen, und das wäre der Zeitpunkt, an dem die' images' dort wären. – JLRishe

Antwort

1

FileReader ist asynchron und nicht die beste Wahl für die Vorschau von Dateien mit base64. Base64 benötigt mehr Speicherplatz und benötigt mehr Zeit zum Dekodieren/Kodieren. Am besten erstellen Sie stattdessen eine object url.

Wenn Sie eine Einzelseitenanwendung erstellen und die Seite nie neu laden, sollten Sie auch auf revoking achten, wenn Sie sie nicht mehr benötigen.

Sie können mit 1 von 2 asynchroner Aufgabe weg (die anderen image.onload sein)

window.URL = window.URL || window.webkitURL 

// Nameing convention: you are passing in files 
// to the function not images, so name it 'files' 

onDrop(files) { 
    this.props.dispatch(setImages(files)) 

    this.props.files.forEach(file => { 
    const url = URL.createObjectURL(file) 
    // render images 
    }) 
} 
Verwandte Themen