'react-native-swiper next/previous button event

The swiper index value comes out in order of page order. However, when the button is pressed, the index value goes up to infinity.

ex) next button click-> 6/5, 7/5, 8/5

What I would like to do is stop the button event on 5/5 but I do not know what to do.

https://github.com/leecade/react-native-swiper

App.js

const renderPagination = (index, total, context) => {

  return (
    <View style={styles.paginationStyle}>
      <Text style={{ color: 'grey' }}>
        <Text style={styles.paginationText}>{index + 1}</Text>/{total}
      </Text>
    </View>
  )
}

export default class App extends Component {

  constructor(props){
    super(props);
    this.onPressNext = this.onPressNext.bind(this);
    this.state = {
      idxActive: 1
    }
 }

  onPressPrev = () => {
    this.refs.swiper.scrollBy(-1)
  }

  onPressNext = () => {
    this.refs.swiper.scrollBy(1);
  }

  render() {
    return (

      <View style={styles.container}>


        <Swiper
          style={styles.wrapper}
          renderPagination={renderPagination}
          showsButtons={false}
          loop={false}
          ref={'swiper'}
        >
          <View style={styles.slide}>
            <Text style={styles.text}>1 page</Text>
          </View>
          <View style={styles.slide}>
            <Text style={styles.text}>2 page</Text>
          </View>
          <View style={styles.slide}>
            <Text style={styles.text}>3 page</Text>
          </View>
          <View style={styles.slide}>
            <Text style={styles.text}>4 page</Text>
          </View>
          <View style={styles.slide}>
            <Text style={styles.text}>5 page</Text>
          </View>
        </Swiper>

        <View style={styles.buttoncontainer}>
          <Button
            onPress={this.onPressPrev}
            title="previous">
          </Button>
          <Button
            onPress={this.onPressNext}
            title="next">
          </Button>

        </View>
      </View>
    );
  }
}


Solution 1:[1]

Use the onIndexedChanged prop of the swiper to get the latest index and save it in your local component state. Something like:

export default class App extends Component {

  constructor(props){
    super(props);
    this.onPressNext = this.onPressNext.bind(this);
    this.onPressPrev = this.onPressPrev.bind(this);
    this.state = {
      idxActive: 0
    }
 }

  onPressPrev = () => {
    const {idxActive} = this.state;
    if (idxActive > 0) {
      this.refs.swiper.scrollBy(-1)
    }
  }

  onPressNext = () => {
    const {idxActive} = this.state;
    // Probably best set as a constant somewhere vs a hardcoded 5
    if (idxActive < 5) {
      this.refs.swiper.scrollBy(1);
    }
  }

  render() {
    return (

      <View style={styles.container}>


        <Swiper
          ... etc.
          onIndexChanged={idxActive => this.setState({idxActive})}
        >
          ... etc.

Solution 2:[2]

here's what helped me, use onIndexChanged prop in swiper, it keeps track of your swiper elements length, the following code snippet is for a functional component.

const [keyNumber, setKeyNumber] = useState(0);
const swiperRef = useRef(null);

const isPrevDisabled = keyNumber < 1;

const isNextDisabled = keyNumber > calloutScreens.length - 2;

const renderPrevButton = () => {
 return (
   <TouchableOpacity
     style={styles.buttonWrapper}
     disabled={isPrevDisabled}
     onPress={() => swiperRef.current?.scrollBy(-1)}>
     <Text
       style={isPrevDisabled ? styles.disabledButton : 
        styles.activeButton}>
      {PREVIOUS}
     </Text>
   </TouchableOpacity>
 );
};

const renderNextButton = () => {
  return (
   <TouchableOpacity
     style={styles.buttonWrapper}
     disabled={isNextDisabled}
     onPress={() => swiperRef.current?.scrollBy(1)}>
     <Text
       style={isNextDisabled ? styles.disabledButton : 
        styles.activeButton}>
       {NEXT}
     </Text>
   </TouchableOpacity>
  );
};

const handleIndexChange = (index: number) => {
 setKeyNumber(index);
};

 return (
  <View style={styles.container}>
    {calloutScreens.length > 0 && (
      <>
        <Swiper
          autoplay={true}
          ref={swiperRef}
          autoplayTimeout={5}
          loop={false}
          activeDotStyle={styles.activeDotStyle}
          dotStyle={styles.inactiveDotStyle}
          showsPagination={true}
          onIndexChanged={handleIndexChange}>
          {renderSwiperContent()}
        </Swiper>
        <View style={styles.footerContainer}>
          {renderPrevButton()}
          <HKButton
            title={BUTTON_TITLE}
            onPress={handleOnboardingCompletion}
          />
          {renderNextButton()}
        </View>
      </>
    )}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2