question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

onIndexChanged this.setState({}) Loop not work

See original GitHub issue

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

  1. use setState onIndexChanged and loop works weird .

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:2
  • Comments:16

github_iconTop GitHub Comments

16reactions
HuiSFcommented, Sep 28, 2017

+1 the same problem. I observed that if call setState in parent component, componentWillReceiveProps of the swiper component gets triggered, and nextProps is exactly as the same as props of current swiper component. And further setState and initState of the swiper component get called, so the swiper state gets messed up.

I temporarily added if (nextProps.index === this.props.index) return; in componentWillReceiveProps to solve this issue.

12reactions
fahmidmecommented, Dec 23, 2019

For me, setting loop={false} worked.

Read more comments on GitHub >

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

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found