2017-11-01 3 views
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

아마도 아니라 "대답"하지만 문제는 조금 모호하다. 이것은 여러 가지면에서 해결 될 수 있습니다.

옵션 하나 : 먼저 배열을로드 한 다음 목록을 표시하고 각 행의 이미지를 비동기 적으로 "sideload"하십시오. 이미지가 많아서 조심해 야합니다. 또한 렌더링하지 못할 수도있는 이미지를 여기에로드 할 수 있습니다 (예 : 사용자가 스크롤하지 않는 등보기가 안됨).하지만 장단점을 두 번로드하지 마십시오.

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 : 하나에 및 해결 다시 쓰게 한 후 번들 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

관련 문제