김회준
김회준

Reputation: 159

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>
    );
  }
}

Upvotes: 6

Views: 9329

Answers (2)

flyingBird
flyingBird

Reputation: 11

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>
      </>
    )}

Upvotes: 1

azundo
azundo

Reputation: 6052

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.

Upvotes: 4

Related Questions