Ich habe eine Komponente, die eine Sammlung von Elementen als Requisiten erhält und map
sie zu einer Sammlung von Komponenten zusammenfügt, die als untergeordnete Elemente einer übergeordneten Komponente gerendert werden. Wir verwenden Bilder, die WebSQL
als Byte-Arrays gespeichert sind . Innerhalb der map
Funktion erhalte ich eine Bild-ID vom Element und rufe das asynchron an DAL
, um das Byte-Array für das Bild zu erhalten. Mein Problem ist, dass ich das Versprechen nicht an React weitergeben kann, da es nicht für Versprechen beim Rendern ausgelegt war (soweit ich das sowieso nicht beurteilen kann). Ich komme aus einem C#
Hintergrund, also suche ich await
wahrscheinlich nach dem Schlüsselwort für die Neusynchronisierung von verzweigtem Code.
Die map
Funktion sieht ungefähr so aus (vereinfacht):
var items = this.props.items.map(function (item) {
var imageSrc = Utils.getImageUrlById(item.get('ImageId')); // <-- this contains an async call
return (
<MenuItem text={item.get('ItemTitle')}
imageUrl={imageSrc} />
);
});
und die getImageUrlById
Methode sieht so aus:
getImageUrlById(imageId) {
return ImageStore.getImageById(imageId).then(function (imageObject) { //<-- getImageById returns a promise
var completeUrl = getLocalImageUrl(imageObject.StandardConImage);
return completeUrl;
});
}
Dies funktioniert nicht, aber ich weiß nicht, was ich ändern muss, damit dies funktioniert. Ich habe versucht, der Kette ein weiteres Versprechen hinzuzufügen, aber dann wird eine Fehlermeldung angezeigt, da meine Renderfunktion ein Versprechen anstelle von legalem JSX zurückgibt. Ich dachte, dass ich vielleicht eine der React
Lebenszyklusmethoden nutzen muss, um die Daten abzurufen, aber da ich die props
bereits dort haben muss, kann ich nicht herausfinden, wo ich das tun kann.
quelle
componentWillMount
anstattcomponentDidMount
kein anfängliches "leeres" Rendern zu haben.componentWillMount
wird vor dem ersten Rendern ausgeführt.var newUrls = self.state.imageUrls.slice().push(mapping)
Der zurückgegebene Wert ist keine flache Kopie des Arrays, sondern die Länge des neuen Arrays. Siehe Array.prototype.push ()Oder Sie können Reaktionsversprechen verwenden:
Installieren Sie das Paket:
Und Ihr Code sieht ungefähr so aus:
import Async from 'react-promise' var items = this.props.items.map(function (item) { var imageSrc = Utils.getImageUrlById(item.get('ImageId')); // <-- this contains an async call return ( <Async promise={imageSrc} then={(val) => <MenuItem text={item.get('ItemTitle')} imageUrl={val}/>} /> ); });
Bearbeiten: Okt 2019
Der letzte Build von React-Promise bietet einen Hook namens
usePromise
:import usePromise from 'react-promise'; const ExampleWithAsync = (props) => { const {value, loading} = usePromise<string>(prom) if (loading) return null return <div>{value}</div>} }
Vollständige Dokumentation: Reaktionsversprechen
quelle