首先,我想解释一下我想做什么以及我的问题出在哪里。
最初我做一个获取请求来加载一些数据,因为这里工作正常。 在使用这个数据的一个值后,我想再做一次获取。为此,我调用另一个函数 renderImage(),在那里我进行获取,然后渲染我想要的代码。
我的问题是没有渲染任何内容,因为没有将状态更改为已加载。当然,fetch是异步的,需要更多时间。 而且我不知道它是如何运作的,而且更简单,因为我认为我这样做有点复杂。
这是我的代码:
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 :(得分: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: 将所有加载捆绑到一个并解决后重新渲染。
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>
)
}
}
}
未经测试的代码,但只是想分享我的想法。