2017-11-01 16 views
1

まず、私が何をしたいのか、そしてどこに問題があるのか​​を説明したいと思います。レンダリングする複数の関数を呼び出す

最初は、ここではokeyが動作しているため、一部のデータを読み込むためのフェッチ要求を行います。 このデータの1つの値の後、別のフェッチを行います。そのために私は別の関数を呼び出しますrenderImage()、ここでフェッチを行い、私が望むコードをレンダリングします。

私の問題は、何も表示していないということです。なぜなら、状態を読み込み中に変更していないからです。もちろん、フェッチは非同期であり、より多くの時間が必要です。 そして、私はそれが少し複雑になっていると思うので、それはどのように機能し、もっと簡単なのか分かりません。

これは私のコードです:おそらく

class Dashboard extends Component{ 

constructor(props){ 
    super(props) 
    this.state = { 
     dataSource: new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2 
     }), 
     loaded: false, 
     datos: '', 
    } 
} 

componentDidMount(){ 
    this.fetchData(); 
} 

    fetchData(){ 
     fetch(REQUEST_URL) 
     .then((response) => response.json()) 
     .then ((responseData) =>{ 
      this.setState({ 
       dataSource: this.state.dataSource.cloneWithRows(responseData), 
      })  
     }) 
    } 

    renderLoadingView(){ 
     return(
      <View> 
      <Text>Cargando...</Text> 
      </View> 
      ) 
    } 

    async renderImage(receta){ 
      const REQUEST_URL = "yyyyyyyy" + receta.user_id; 
      const response = await fetch(REQUEST_URL); 
      const json = await response.json(); 
      this.setState({ loaded : true});  
      return(  
        <Card > 
         <CardItem> 
          <Left> 
          <TouchableOpacity> 
          <Thumbnail style={{width: 50, height: 50, borderRadius: 25}} source={{uri: json.imageUrl}} />  
          </TouchableOpacity> 
           <Body> 
            <Text>{receta.Titulo}</Text> 
            <Text>{receta.Username}</Text> 
           </Body> 
          </Left> 
         </CardItem> 
        </Card>    
      )   
    } 


    renderReceta(receta){ 
      return this.renderImage(receta);     
    } 

    render(){  
     if(!this.state.loaded){ 
      return this.renderLoadingView(); 
     } 
     else{ 
      return(
      <Container> 
       <ListView 
       dataSource={this.state.dataSource} 
       renderRow={this.renderReceta.bind(this)} 
       /> 
       </Container> 
       ) 
     } 

    } 

} 
+0

'renderReceta'と' renderImage'と実行する他の関数を返す必要があります – bennygenel

+0

@bennygenelありがとう!私はそれを変更しましたが、まだ動作していません。今すぐループに入り、何も返さない – dddddrrrrrr

+1

あなたのリストアイテムをレンダリングしている間に状態を設定しています。これは再レンダリングをトリガーし、別の状態設定をトリガーし、再レンダリングをトリガーします... – bennygenel

答えて

0

「答え」ではないが、質問は少しあいまいです。これは多くの方法で解決できます。

オプション1: 最初に配列をロードしてから、リストを表示し、各行の画像を非同期に "サイドロード"します。 たくさんの画像があるので気になるので注意してください。また、画像をここにロードすると、決してレンダリングされないかもしれません(ユーザーは表示されません)。ただし、賛否両論に2度も表示されません。

class Dashboard extends Component{ 

    constructor(props){ 
     super(props) 
     this.state = { 
      dataSource: new ListView.DataSource({ 
       rowHasChanged: (row1, row2) => row1 !== row2 
      }), 
      loaded: false, 
      datos: '', 
      images: { 

      } 
     } 
    } 

    componentDidMount(){ 
     this.fetchData(); 
    } 

    fetchData(){ 
     fetch(REQUEST_URL) 
      .then((response) => response.json()) 
      .then ((responseData) =>{ 
       this.setState({ 
        loaded: true, 
        dataSource: this.state.dataSource.cloneWithRows(responseData), 
       }); 
       this.fetchImageUrls(responseData); 
      }); 
    } 

    fetchImageUrls(responseData){ //assuming respons data is an array of receta objects 
     responseData.forEach(({user_id})=>{ 
      fetch("wwwsomewhere").then(r => r.json()).then(({imageUrl})=>{ 
       this.setState({ 
        images: Object.assign(this.state.images, { 
         [user_id]: imageUrl 
        }) 
       }); 
      }); 
     }); 
    } 

    renderLoadingView(){ 
     return(
      <View> 
       <Text>Cargando...</Text> 
      </View> 
     ) 
    } 

    renderImage(receta){ 
     const {Titulo, Username, user_id} = receta; 
     return(
      <Card > 
       <CardItem> 
        <Left> 
         <TouchableOpacity> 
          {this.state.images[user_id] ? 
           <Thumbnail style={{width: 50, height: 50, borderRadius: 25}} source={{uri: this.state.images[user_id]}} /> 
           : "Loading (load thumb here?)" 
          } 
         </TouchableOpacity> 
         <Body> 
         <Text>{receta.Titulo}</Text> 
         <Text>{receta.Username}</Text> 
         </Body> 
        </Left> 
       </CardItem> 
      </Card> 
     ) 
    } 


    renderReceta(receta){ 
     return this.renderImage(receta); 
    } 

    render(){ 
     if(!this.state.loaded){ 
      return this.renderLoadingView(); 
     } 
     else{ 
      return(
       <Container> 
        <ListView 
         dataSource={this.state.dataSource} 
         renderRow={this.renderReceta.bind(this)} 
        /> 
       </Container> 
      ) 
     } 
    } 
} 

オプション2:1にし、解決の再レンダリング後の バンドルUPPすべてのロード。

class Dashboard extends Component{ 

    constructor(props){ 
     super(props) 
     this.state = { 
      dataSource: new ListView.DataSource({ 
       rowHasChanged: (row1, row2) => row1 !== row2 
      }), 
      loaded: false, 
      datos: '', 
      recetas: { 

      } 
     } 
    } 

    componentDidMount(){ 
     this.fetchData(); 
    } 

    fetchData(){ 
     fetch(REQUEST_URL) 
      .then((response) => response.json()) 
      .then ((responseData) =>{ 
       this.setState({ 
        dataSource: this.state.dataSource.cloneWithRows(responseData), 
       }); 
       this.fetchImageUrls(responseData); 
      }); 
    } 

    fetchImageUrls(responseData){ //assuming respons data is an array of receta objects 
     //Load all images 
     Promise.all(responseData.map(({user_id})=>{ 
      return fetch("wwwsomewhere").then(r => r.json()); 
     })).then((recetasArray)=>{ 
      //When all thumb objects (Recetas) have been resolved 
      //map over the receta object array and create a hash (so you can access them by id later) 
      this.setState({ 
       loaded: true, 
       recetas: recetasArray.reduce((acc, receta)=>{ 
        acc[recept.user_id] = receta; 
        return acc; 
       },{}) 
      }); 
     }); 
    } 

    renderLoadingView(){ 
     return(
      <View> 
       <Text>Cargando...</Text> 
      </View> 
     ) 
    } 

    renderImage(receta){ 
     const {Titulo, Username, user_id} = receta; 
     return(
      <Card > 
       <CardItem> 
        <Left> 
         <TouchableOpacity> 
          <Thumbnail style={{width: 50, height: 50, borderRadius: 25}} source={{uri: this.state.recetas[user_id]}} /> 
         </TouchableOpacity> 
         <Body> 
         <Text>{receta.Titulo}</Text> 
         <Text>{receta.Username}</Text> 
         </Body> 
        </Left> 
       </CardItem> 
      </Card> 
     ) 
    } 


    renderReceta(receta){ 
     return this.renderImage(receta); 
    } 

    render(){ 
     if(!this.state.loaded){ 
      return this.renderLoadingView(); 
     } 
     else{ 
      return(
       <Container> 
        <ListView 
         dataSource={this.state.dataSource} 
         renderRow={this.renderReceta.bind(this)} 
        /> 
       </Container> 
      ) 
     } 
    } 
} 

未知のコードですが、私の考えを共有したかっただけです。

+0

ありがとう!!私はいくつかのことを変えましたが、今は働いています再度、感謝します! – dddddrrrrrr

関連する問題