onLoadEnd not firing in react native

早过忘川 提交于 2020-05-27 05:53:49

问题


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;


回答1:


One thing that seems wrong here is the getGiphy and renderQuotes properties that are not arrow functions or don't bind "this" in the constructor. Judging by your code, you can't use the setState function cause of the wrong "this" scope.

Try this to see if this works

getGiphy = () => {...}
renderQuotes = () => {...}

Are you sure you don't get an error like "setState is undefined"?




回答2:


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.



来源:https://stackoverflow.com/questions/50188373/onloadend-not-firing-in-react-native

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!