'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 |