onIndexChanged this.setState({}) Loop not work
See original GitHub issueWhich 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 .
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:16
Top Results From Across the Web
react setstate does not work properly on loops - Stack Overflow
Try using the Fat Arrow approach to set state as follows: setLocalErrs(localErrs => ({ ...localErrs, [single.param]: single.msg }));.
Read more >Call a function that do setState() in a for loop : r/reactjs - Reddit
Hi, i have a for loop, and i have to do update an array. ... setState() does not immediately mutate this.state but creates...
Read more >[Solved]-react-native-swiper method scrollBy-React Native
React Native - Create method in functional component and call this method outside of the component, possible? React Native swiper not working in...
Read more >React.Component
The render() function should be pure, meaning that it does not modify component state, ... You should not call setState() in the constructor()...
Read more >Why React doesn't update state immediately - LogRocket Blog
To update state in React components, we'll use either the this.setState function or the updater function returned by the React.useState() Hook ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
+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.