アイテムのコレクションを小道具として取得し、それらを親コンポーネントの子としてレンダリングされるコンポーネントのコレクションにmap
sするコンポーネントがあります。 WebSQL
に格納されている画像をバイト配列として使用します。 map
関数内で、アイテムから画像IDを取得し、DAL
への非同期呼び出しを行って、画像のバイト配列を取得します。私の問題は、レンダリングのプロミスを処理するように設計されていないため、プロミスをReactに伝達できないことです(とにかく伝えることができる限りではありません)。私はC#
バックグラウンドから来ているので、分岐コードを再同期するためのawait
キーワードのようなものを探していると思います。
map
関数は次のようになります(簡略化)。
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} />
);
});
getImageUrlById
メソッドは次のようになります。
getImageUrlById(imageId) {
return ImageStore.getImageById(imageId).then(function (imageObject) { //<-- getImageById returns a promise
var completeUrl = getLocalImageUrl(imageObject.StandardConImage);
return completeUrl;
});
}
これは機能しませんが、この機能を実現するために何を変更する必要があるのかわかりません。別のプロミスをチェーンに追加しようとしましたが、レンダリング関数が正当なJSXではなくプロミスを返すため、エラーが発生します。 React
ライフサイクルメソッドの1つを利用してデータを取得する必要があるかもしれないと考えていましたが、props
が既に存在する必要があるため、どこでできるかわかりません。これを行う。
render()
メソッドはthis.propsとthis.stateからUIをレンダリングする必要があるため、データを非同期にロードするには、this.state
を使用してimageId:imageUrl
マッピングを保存できます。
その後、componentDidMount()
メソッドで、imageIdからimageUrlを設定できます。 render()
メソッドは、this.state
オブジェクトをレンダリングすることにより、純粋でシンプルなものでなければなりません。
簡単なサンプルコードを次に示します。this.state.imageUrls
は非同期に設定されるため、URLが取得された後、レンダリングされた画像リストアイテムが1つずつ表示されることに注意してください。 this.state.imageUrls
をすべての画像IDまたはインデックス(URLなし)で初期化することもできます。これにより、画像の読み込み中にローダーを表示できます。
constructor(props) {
super(props)
this.state = {
imageUrls: []
};
}
componentDidMount() {
var self = this;
this.props.items.map((item) => {
ImageStore.getImageById(item.imageId).then(image => {
var mapping = {id: item.imageId, url: image.url};
var newUrls = self.state.imageUrls.slice();
newUrls.Push(mapping);
self.setState({
imageUrls: newUrls
});
})
});
}
render() {
return (<div>
this.state.imageUrls.forEach(mapping => {
<div>id: {mapping.id}, url: {mapping.url}`</div>
})
</div>
);
}
または、react-promiseを使用できます。
パッケージをインストールします。
npm i react-promise
コードは次のようになります。
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}/>} />
);
});
完全なドキュメント: react-promise