react-native-swiper: onIndexChanged this.setState({}) Loop not work
Which OS
ios 10.3 android 6.0
Version
Which versions are you using:
- react-native-swiper v1.5.12
- react-native v0.47.2
Expected behaviour
Actual behaviour
On Android and IOS I can only swipe 1 to the left from 0 and no more (4/4). And swipe 4 to the right and no more (1/4). The problems here is for some reason the loop brake in a strange way. I try different things. And I found the problem is cause by this.setState in the onIndexChanged function which if I don’t use it, the loop works.
How to reproduce it>
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react'
import {
Text,
View,
Image,
Dimensions,
AppRegistry
} from 'react-native'
import Swiper from 'react-native-swiper'
const { width } = Dimensions.get('window')
const styles = {
wrapper: {
},
slide: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'transparent'
},
text: {
color: '#fff',
fontSize: 30,
fontWeight: 'bold'
},
image: {
width,
flex: 1
},
paginationStyle: {
position: 'absolute',
bottom: 10,
right: 10
},
paginationText: {
color: 'white',
fontSize: 20
}
}
var imageName = './img/1.jpg';
var originalName = 'Aussie tourist dies at Bali hotel';
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 AwesomeProject extends Component {
constructor(props) {
super(props);
this.state = {
renderArray: [true, false, false, false]
};
}
render() {
return (
<Swiper
style={styles.wrapper}
onIndexChanged={index => this.indexChanged(index)}
renderPagination={renderPagination}
loop={true}
>
<View style={styles.slide} title={<Text numberOfLines={1}>{'Aussie tourist dies at Bali hotel'}</Text>}>
{this.state.renderArray[0] ?
<Image style={styles.image} source={require('./img/1.jpg')} />
: null}
</View>
<View style={styles.slide} title={<Text numberOfLines={1}>Big lie behind Nine’s new show</Text>}>
{this.state.renderArray[1] ?
<Image style={styles.image} source={require('./img/2.jpg')} />
: null}
</View>
<View style={styles.slide} title={<Text numberOfLines={1}>Why Stone split from Garfield</Text>}>
{this.state.renderArray[2] ?
<Image style={styles.image} source={require('./img/3.jpg')} />
: null}
</View>
<View style={styles.slide} title={<Text numberOfLines={1}>Learn from Kim K to land that job</Text>}>
{this.state.renderArray[3] ?
this.renderImage4()
: null}
</View>
</Swiper>
)
}
renderImage4(){
return <Image style={styles.image} source={require('./img/4.jpg')} />;
}
indexChanged(index) {
var tempvar = this.state.renderArray;
tempvar[index] = true
this.setState({ renderArray: tempvar}); //<<======== problem with this
}
}
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
Steps to reproduce
- use setState onIndexChanged and loop works weird .
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 2
- Comments: 16
Commits related to this issue
- onIndexChanged this.setState({}) Loop does not work. fixed by removing commit 1fb7ff2 https://github.com/leecade/react-native-swiper/issues/569 — committed to jinglinwishlife/react-native-swiper by jinglinwishlife 6 years ago
- onIndexChanged this.setState({}) Loop does not work. fixed by removing commit 1fb7ff2 https://github.com/leecade/react-native-swiper/issues/569 — committed to m-matsuura/react-native-swiper by jinglinwishlife 6 years ago
- Update index.js Solves the issue of state messing up when parent component calls setState [ref https://github.com/leecade/react-native-swiper/issues/569] — committed to deepakaggarwal7/react-native-swiper by deepakaggarwal7 5 years ago
- Update index.js Solves the issue of state messing up when parent component calls setState [ref https://github.com/leecade/react-native-swiper/issues/569] — committed to rauljurado620/react-native-swiper by rauljurado620 5 years ago
+1 the same problem. I observed that if call
setState
in parent component,componentWillReceiveProps
of the swiper component gets triggered, andnextProps
is exactly as the same asprops
of current swiper component. And furthersetState
andinitState
of the swiper component get called, so the swiper state gets messed up.I temporarily added
if (nextProps.index === this.props.index) return;
incomponentWillReceiveProps
to solve this issue.For me, setting
loop={false}
worked.@arribbar I had so probiems after this commit https://github.com/leecade/react-native-swiper/commit/1fb7ff24cf2adb3bbe2feb487e9ac88c97c603a6
I removed this code and it works.
setTimeout seemed to fix the warning
Warning: Cannot update a component from inside the function body of a different component.
for me but the second slide style was breaking for me. When I swipe to the second slide, it would be offset to the left and only on clicking it, it would align right. After a lot of trial and error, addingloadMinimal={true}
is what did the trick. loop was still set to true.Exactly the same problem for me on
"react-native-swiper": "^1.5.12"
@ronayumik
that works for me, the
this.setState
doesn’t work withloop={true}