I am trying to display GIF from the giphy api on react native. Gifs take time to display on screen so I want to display a spinner on the midtime. The onLoadEnd event seem to be never fired on the Image tag, so the spinner actually runs endlessly because I can never update loading in my state. What am I doing wrong here ?
import React, { Component } from 'react';
import { View, Text, ScrollView, Image} from 'react-native';
import axios from 'axios';
import QuoteDetail from './quote_detail'
import Spinner from './spinner'
// class based component knows when it's gona be rendered
class QuoteList extends Component {
state = { quotes: [],
giphyUrl: 'https://media.giphy.com/media/nZQIwSpCXFweQ/giphy.gif',
loading: true
};
componentWillMount() {
console.log('Again?')
axios.get('https://api.tronalddump.io/search/quote?query='+this.props.characterName)
.then(response => this.setState({ quotes: response.data._embedded.quotes }))
this.getGiphy()
}
getGiphy() {
console.log('getgif')
const GiphyUrl = "https://api.giphy.com/v1/gifs/search?api_key=mBJvMPan15t7TeLs8qpyEZ7Glr5DUmgP&limit=1&q=" + this.props.characterName.replace(" ", "+");
console.log(GiphyUrl)
axios.get(GiphyUrl)
.then(response => {
console.log(response)
console.log(response.data.data[0].url)
this.setState({ giphyUrl: response.data.data[0].images.original.url})
console.log(this.state)
})
}
renderQuotes() {
return this.state.quotes.map(
quote => <QuoteDetail key={quote.quote_id} quote={quote}/>
);
}
render() {
if (this.state.loading) {
return < Spinner />;
}
else {
return (
<ScrollView>
<View style={styles.viewStyle}>
<Image
source={{uri: this.state.giphyUrl}}
key={this.state.giphyUrl}
style={styles.gifStyle}
onLoadEnd={() => console.log('im done loading')}
/>
<Text style={styles.vsStyle}>VS</Text>
<Image
source={{ uri: "https://media.giphy.com/media/xTiTnHXbRoaZ1B1Mo8/giphy.gif"}}
key="https://media.giphy.com/media/xTiTnHXbRoaZ1B1Mo8/giphy.gif"
style={styles.gifStyle}
/>
</View>
{this.renderQuotes()}
</ScrollView>
);
}
}
}
const styles = {
gifStyle: {
height: 200,
width: 190
},
viewStyle: {
flexDirection: 'row'
},
vsStyle: {
marginTop: 95,
marginLeft: 5,
marginRight: 5,
fontWeight: 'bold',
fontSize: 20
}
};
export
default QuoteList;
Your component mounts with the state property 'loading' set to true. In your render method, you're conditionally rendering either your spinner -or- your image-containing scrollview based on whether 'loading' is true, and I'm not seeing any place in your code example where 'loading' is ever set to false. This means that your <Image />
is never rendered, so it never loads in the first place, so the onLoadEnd will never be called.
I would still only conditionally render the spinner, but would approach it more like this:
render() {
return (
<View>
<ScrollView>
<View style={styles.viewStyle}>
<Image
source={{uri: this.state.giphyUrl}}
key={this.state.giphyUrl}
style={styles.gifStyle}
onLoadEnd={() => this.setState({loading: false})}
/>
<Text style={styles.vsStyle}>VS</Text>
<Image
source={{uri:"https://media.giphy.com/media/xTiTnHXbRoaZ1B1Mo8/giphy.gif"}}
key="https://media.giphy.com/media/xTiTnHXbRoaZ1B1Mo8/giphy.gif"
style={styles.gifStyle}
/>
</View>
{this.renderQuotes()}
</ScrollView>
{this.state.loading && <Spinner />}
</View>
);
}
Give your spinner an absolute position so that it renders over the scrollview.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With