React-native-swiper: onIndexChanged errors

Created on 8 Nov 2017  路  7Comments  路  Source: leecade/react-native-swiper

Which OS

IOS

Version

Which versions are you using:

  • react-native-swiper 1.15.13
  • react-native v0.39

Expected behaviour

The onIndexChanged should return correct values

Actual behaviour

I'm currently moving from one swiper to another and by doing this, functionality is broken

 onIndexChanged={(index) => {
   console.log('index >>> ', index);
   this.setState({
      currentPage: index
   })
}}
'index >>> ', 1
'index >>> ', 2
'index >>> ', 0
'index >>> ', 3 // HERE JUMPS

ezgif-5-3c7d2a6856

jumps from 0 to 3, seems to try to continue from the value that was just before restarting the swiper


I have found other error scenarios

Examples:

ezgif-5-12ebc7eab1

in this case i have a fixed bottom view

let bottomView = <View style={{ flex: 0.08, backgroundColor: theme.colors.transparent }} />;


ezgif-5-b321244a31

In this case the bottom view only appear when last active dot comes in.

bottomView = null


I get the impression that every time the NEXT button appears and updates the ui, the swiper breaks

Example code:

buildOnboardingSteps(currentSection) {
  let { lastPage, title, baseText, swiperImages } = this.applyViewRenderValidations(currentSection);
  let bottomView = null; // Second Gif
  // let bottomView = <View style={{ flex: 0.08, backgroundColor: theme.colors.transparent }} />; // First gif

  if (this.state.currentPage === lastPage) {
    bottomView = (
      <TouchableOpacity style={[styles.bottomView]} onPress={() => { this.passToNextSection() }}>
        <Text style={[styles.baseText, styles.nextText]}>{'NEXT'}</Text>
      </TouchableOpacity>
    )
  }
  return (
    <Animatable.Image style={styles.container} source={undefined} animation={'slideInRight'} duration={500}>
      <View style={[styles.topView, styles.topViewAddItem]}>
        <Text style={styles.baseTitle}>{title}</Text>
        <Text style={styles.baseText}>{baseText}</Text>
        <Swiper
          style={styles.wrapper}
          activeDotColor={theme.colors.swiperDotColor}
          showsPagination={true}
          scrollsToTop={true}
          loop={false}
          onIndexChanged={(index) => {
            console.log('index >>> ', index);
            this.setState({
              currentPage: index
            })
          }}
        >
          {swiperImages}
        </Swiper>
      </View>
      {bottomView}
    </Animatable.Image>
  )
}

Most helpful comment

Using state, onIndexChange/setState, and index prop, AND giving the Swiper an explicit width prop that's not falsy fixed this for me, as well.

handleSwipeIndexChange = index => {
    this.setState({ index });
  };
<Swiper
    autoplay={false}
    loop={false}
    removeClippedSubviews={false}
    dotColor={Colors.lightGray}
    activeDotColor={Colors.darkGray}
    onIndexChanged={this.handleSwipeIndexChange}
    height={250}
    width={WIDTH}
    index={this.state.index}
>
    {swipeableStuff}
</Swiper>

All 7 comments

I'm having same problem, have you got any solution?? I'm surprised that, no one raise this kind is serious issue yet.

I just want to set status of current index but it's misbehaving, like..
on first slide load, it's not return any thing.. obviously.. then i slide right..
it displaying content of slide 3 direct, but dot showing slide 2 & slide left not work, then i slide right..
it displaying content of slide 1, do showing slide 1,
further process working fine...
but having issue on first complete slider..

hi @chixpc123 .

I found a solution, but in a very unorthodox way.

Clearly, as is the code of my example, it should be enough for it to work, but I had to resort to 3 things:

1) Use the basic prop index, so every time I was updating the index with theonIndexChange that value put it as the index prop of the swiper.

2) Give it a width. As a direct prop in theswiper instead a width inside style. You can see it in Custom basic style & content.

3) In my code the view container of the swiper had a paddingLeft I had to remove it and give the margins to the left to each child in the swiper

Using state, onIndexChange/setState, and index prop, AND giving the Swiper an explicit width prop that's not falsy fixed this for me, as well.

handleSwipeIndexChange = index => {
    this.setState({ index });
  };
<Swiper
    autoplay={false}
    loop={false}
    removeClippedSubviews={false}
    dotColor={Colors.lightGray}
    activeDotColor={Colors.darkGray}
    onIndexChanged={this.handleSwipeIndexChange}
    height={250}
    width={WIDTH}
    index={this.state.index}
>
    {swipeableStuff}
</Swiper>

I'm also seeing this issue, and it appears to be occurring anytime I call setState, regardless of whether or not it's inside onIndexChange. However, in the below example, if I remove the bottom margin, it doesn't seem to have the issue any more.

class Splash extends Component {
  state: { hasTracked: boolean } = { hasTracked: false };

  componentWillMount() {
    setTimeout(() => {
      this.setState({ hasTracked: true });
      console.log('ss');
    }, 5000);
  }

  render() {
    return (
      <View style={{ flex: 1, marginBottom: 20 }}>
        <Swiper>
          <View style={{ flex: 1, borderColor: 'red', borderWidth: 2 }} />
          <View style={{ flex: 1, borderColor: 'green', borderWidth: 2 }} />
          <View style={{ flex: 1, borderColor: 'blue', borderWidth: 2 }} />
        </Swiper>
      </View>
    );
  }
}

@wkoutre 's code worked for me too. Cant set any other pieces of state in the onIndexChanged call though, even after index has been set. Such a strange bug

@leecade can you help solving the issue?.

@kevinEsherick Have you tried setting the rest of your state in the callback for setting the index鈥檚 state?

this.setState({ index ), () => { ...setting other state })
Was this page helpful?
0 / 5 - 0 ratings

Related issues

gwhite-dayspring picture gwhite-dayspring  路  3Comments

agzuniverse picture agzuniverse  路  3Comments

ghost picture ghost  路  3Comments

Liqiankun picture Liqiankun  路  3Comments

tokict picture tokict  路  3Comments