react-native-swiper: Update the state breaks the slides.

Which OS ?

MAC OS

Version

Which versions are you using: ^1.6.0-nightly.3

  • react-native-swiper v?
  • react-native v0.59.5

Hello Guys, I am using Swiper like this:

renderThumb() {
        return (
            <Swiper style={styles.wrapper} showsButtons={false} horizontal={false} showsPagination={false} loop={false} onIndexChanged={this.onSlideIndexUpdate} onMomentumScrollEnd={() => { console.log('on touch end') }}>
                {this.state.cachedThumbnails.map((thumb) => {
                    console.log('HERE THUMB', thumb)
                    return (
                        <View key={thumb.key} style={styles.thumbnailContainer}>
                            <Loader loading={this.state.showThumbnail} withBackground={false} showLoadingText={false} />
                            <Image
                                source={{ uri: thumb.thumbLink }}
                                style={styles.backgroundVideo}
                                resizeMode='cover'
                            />
                  
                        </View>
                    );
                })}
            </Swiper>
        );
    };

Every time when the state is changed, the component is re-rendered, but the slide is pushed up and the next slide is seeing from the bottom, as showed here in the image:

Please note, this happens only on the images with index>0. If I swipe to the first slide, the slide is ok.

Screen Shot 2019-09-05 at 16 39 46

Screen Shot 2019-09-05 at 16 39 55

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 6
  • Comments: 34

Commits related to this issue

Most upvoted comments

If set prop loadMinimal it works in my case.

As it stands the lib seems completely unusable due to this. Building from @hanford 's advice, the following seems to fix the issue on the latest version. https://github.com/kyle-ssg/react-native-swiper/commit/eeddedb4205d28c79853f8d39b2fa5750d254069#diff-1fdf421c05c1140f6d71444ea2b27638

Looks like some internal state values aren’t being included when rendering, maybe it could just use this.internals.offset. Added a PR for this.

Just remove contentOffset={this.state.offset} line in src/index.js.

same issue here

I’m experiencing something very similar. Everything works great until I add onIndexChanged.

My code looks something like this:

function (props: Props) {
  const questions = idx(props, _ => _.viewer.findSurvey.questions) || [];
  const name = idx(props, _ => _.viewer.findSurvey.name);
  const [page, setCurrentPage] = React.useState(0)
  console.log({ page })

  return (
    <Shell title={name}>
      <Swiper
        showsVerticalScrollIndicator={true}
        horizontal={false}
        loop={false}
        showsPagination={false}
        onIndexChanged={page => setCurrentPage(page)}
      >
        {questions.map(item => {
          return (
			<View ...

Using Expo and the latest version of this library.

Happy to share more if it’s helpful!

Thanks @ochikov I downgraded to 1.5.5 and it fixed my issue whereby my slides were automatically half swiping (possibly due to state change)

P.S. 1.5.6 wasn’t available in the versions list (npm view <package> versions)

Just remove contentOffset={this.state.offset} line in src/index.js.

this helped me

I used a translator, the comment may not be delivered well.

in my case, If the swiper is in the modal, it is twisted by the difference between the width of the modal and the width of the device.

A twist occurred a few seconds after the slide was moved.

Ios worked as a loadMinimal.

android worked

I’m experiencing something very similar. Everything works great until I add onIndexChanged.

My code looks something like this:

function (props: Props) {
  const questions = idx(props, _ => _.viewer.findSurvey.questions) || [];
  const name = idx(props, _ => _.viewer.findSurvey.name);
  const [page, setCurrentPage] = React.useState(0)
  console.log({ page })

  return (
    <Shell title={name}>
      <Swiper
        showsVerticalScrollIndicator={true}
        horizontal={false}
        loop={false}
        showsPagination={false}
        onIndexChanged={page => setCurrentPage(page)}
      >
        {questions.map(item => {
          return (
			<View ...

Using Expo and the latest version of this library.

Happy to share more if it’s helpful!

but It only worked on Android autoPlay. After several attempts, we used useMemo, which worked well.

Example)

const memoSwiper = useMemo(() => {
   return (
       <Swiper
         loop={true}
       >
        {Imagelist.map((data) => {<image/>})}
      </Swiper>
   );
}, [])

I used ‘useMemo’ as a guess that it might be an index or offset state problem and solved the problem but I couldn’t find the exact cause

@kyle-ssg when the solution will be merged?

Having worked with various versions of this Swiper over the last month, I can confirm that there is definitely something not right with the very latest versions and I’ve had to settle on v. 1.5.14. The issue seems to be around the new ‘scrollTo’ methods that get in a muddle when updating the slides with dynamic content or changing their length on the fly.

Occasionally, when updating the state of the page (and causing a re-render), the ‘onIndexChanged’ is getting fired off, and reports an index of -1. Any attempt to update state within the callback triggers it to fire off yet again and go to -2 / -3 ad infinitum.

I think this new ‘scrollTo’ thing needs a lot more serious thought and testing, as it seems too unreliable for my liking at present.

@hanford I have downgrade to 1.5.6

@hanford Switching the versions fix the problem!