2015-10-20 6 views
35

私は、アイテムのコレクションを小道具とし、mapを親コンポーネントの子としてレンダリングされるコンポーネントのコレクションに持っているコンポーネントを持っています。 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が必要なので、私はこれをどこで行うことができないのか分かりません。

答えて

59

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なし)で初期化することもできます。この方法で、画像がロードされているときにローダーを表示できます。

​​
+0

いいえ、要点。あなたは例を見せてもらえますか? –

+4

ありがとうございました!それがトリックでした。私がここで変更する唯一のことは、少なくとも "空"のレンダリングを持たないために、 'componentDidMount'ではなく' componentWillMount'でこれを行うことです。 'componentWillMount'は初期レンダリングの前に実行されます。 –

+1

@Wintこの行にはエラーがあります:返される値は配列の浅いコピーではなく、新しい配列の長さであるため、 'var newUrls = self.state.imageUrls.slice()。push(mapping)'です。 [Array.prototype.push()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push#Syntax) – jherax

6

またはあなただけで反応し、約束を使用することができます。

は、パッケージのインストール:

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}/>} />  
    ); 
}); 

完全ドキュメント: https://github.com/capaj/react-promise