question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

onIndexChanged is not triggered if state is set after fetch

See original GitHub issue

Which OS ?

Android

Version

Which versions are you using:

  • react-native-swiper v? 1.5.13
  • react-native v0.?.? 0.51

Expected behaviour

When data is fetched from remote network, onIndexChanged to work.

Actual behaviour

onIndexChanged is not triggered

Steps to reproduce

Below is a sample screen code.

import React, { Component } from "react";
import {
  View,
  Text,
  ImageBackground,
  StyleSheet,
  Dimensions
} from "react-native";
import Swiper from "react-native-swiper";

export default class TestSwiper extends Component {
  constructor(props) {
    super(props);
    this.state = {
      dataMovies: []
    };
  }

  componentDidMount() {
    this.getJsonData().then(dataMovies => {
      this.setState({
        dataMovies: dataMovies
      });
    });
  }
  getJsonData = () => {
    return new Promise((resolve, reject) => {
      fetch("https://facebook.github.io/react-native/movies.json")
        .then(response => response.json())
        .then(responseJson => {
          resolve(responseJson.movies);
        })
        .catch(error => {
          console.error(error);
        });
    });
  };

  swiperIndexChanged = index => {
    console.log("swiperIndexChanged", "index", index);
  };

  onScrollEnd = (e, state) => {
    console.log("Index is:", state.index);
  };

  renderMovie = () => {
    let movieView: any;

    movieView = this.state.dataMovies.map((item, key) => {
      return (
        <View key={key}>
          <Text>{item.title}</Text>
        </View>
      );
    });

    return movieView;
  };

  render() {
    return [
      <View style={{ flex: 1, justifyContent: "space-between" }} key="mainView">
        <Swiper
          loadMinimal={false}
          style={{ flex: 1, justifyContent: "space-between" }}
          onIndexChanged={index => {
            console.log("onindexchanged");
            this.swiperIndexChanged(index);
          }}
          loop={false}
          showButtons={true}
          onMomentumScrollEnd={this.onScrollEnd}
        >
          {this.renderMovie()}
        </Swiper>
      </View>
    ];
  }
}

Swiper functions correctly but onIndexChanged is not triggered.

If we change the componentDidMount function as follow, and just set the “dataMovies” state directly, the onIndexChanged is triggered.

componentDidMount() {
       this.setState({
      dataMovies: MoviesData.movies
    });
    
  }

I am not sure if this is caused by swiper or it is something about setting the state after the fetch call.

Any comments on what could be cause of index change not working in the first case

Thank you

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:7

github_iconTop GitHub Comments

34reactions
narcissus571commented, Sep 14, 2018

u can try this way

Swiper key={this.state.banners.length} /Swiper

3reactions
ozmaatcommented, Dec 28, 2017

Not sure why swiper functioned as it should except the onIndexChanged but it works when you postpone the rendering till the data is ready.

Working code is below if anyone else experience the same problem.

import React, { Component } from "react";
import {
  View,
  Text,
  ImageBackground,
  StyleSheet,
  Dimensions
} from "react-native";
import Swiper from "react-native-swiper";
import MoviesData from "./movies.json";

export default class TestSwiper extends Component {
  constructor(props) {
    super(props);
    this.state = {
      dataMovies: [],
      loadData: false
    };
  }

  componentDidMount() {
    /*    this.setState({
      dataMovies: MoviesData.movies
    });
    */
    this.getJsonData().then(dataMovies => {
      /*this.setState({
        dataMovies: dataMovies
      });*/
    });
  }
  getJsonData = () => {
    return new Promise((resolve, reject) => {
      fetch("https://facebook.github.io/react-native/movies.json")
        .then(response => response.json())
        .then(responseJson => {
          this.setState({
            dataMovies: responseJson.movies,
            loadData: true
          });
          resolve(responseJson.movies);
        })
        .catch(error => {
          console.error(error);
        });
    });
  };

  swiperIndexChanged = index => {
    console.log("swiperIndexChanged", "index", index);
  };

  onScrollEnd = (e, state) => {
    console.log("Index is:", state.index);
  };

  renderMovie = () => {
    let movieView: any;

    movieView = this.state.dataMovies.map((item, key) => {
      return (
        <View key={key}>
          <Text>{item.title}</Text>
        </View>
      );
    });

    return movieView;
  };

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

  render() {
    if (this.state.loadData) {
      return [
        <View
          style={{ flex: 1, justifyContent: "space-between" }}
          key="mainView"
        >
          <Swiper
            loadMinimal={false}
            style={{ flex: 1, justifyContent: "space-between" }}
            onIndexChanged={index => {
              console.log("onindexchanged");
              this.swiperIndexChanged(index);
            }}
            loop={false}
            showButtons={true}
            onMomentumScrollEnd={this.onScrollEnd}
          >
            {this.renderMovie()}
          </Swiper>
        </View>
      ];
    } else {
      return this.renderLoadingView();
    }
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

React state not updating after fetch .then statement
The state seems to not be updating before the console.log is called but it's my understanding that this is asynchronous code and each...
Read more >
SelectionChangeCommitted and SelectedIndexChanged
Hi,. I was having problem with Combo-box which was getting fired while fetching data from DB. Then I used SelectionChangeCommitted so that ...
Read more >
Fetching Data and Updating State with React Hooks - Pluralsight
When a component is created without using a class, but instead with a normal function declaration, it is called a Functional Component. In...
Read more >
CSLA Forum Archive Index
04 Dec 2013 - How do you get CSLA 3.02 BusinessListBase ListChanged event to identify the child object whose OnPropertyChanged triggered the event?...
Read more >
RadioButtonList Postback issue when selected by code behind.
I have a radio button list on my page with three options "Yes", "No" and "Maybe". It has AutoPostBack set to true to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found