leecade / react-native-swiper

The best Swiper component for React Native.
MIT License
10.41k stars 2.34k forks source link

Dot does not work properly while rendering dynamic array components #720

Open uuau99999 opened 6 years ago

uuau99999 commented 6 years ago

Which OS ?

IOS 11.2 / android 7.0

Version

Which versions are you using:

Expected behaviour

pagination active dot will be placed according to the current screen index of swiper while rendering

Actual behaviour

while rendering dynamic components(eg. rendering screens in an array or use map) active dot will remain at the initial position no matter which current swiper screen is active

How to reproduce it>

while rendering dynamic components(eg. rendering screens in an array or use map) active dot will remain at the initial position no matter which current swiper screen is active

Steps to reproduce

  1. set pagingEnabled true
  2. use map to render screens inside a Swiper
  3. try to swipe the screens and the active dot below remains the same position

PS: I tried to use onMomentumScrollEnd and onIndexChanged to monitor the index changes but neither works in the given situation. But when you use rendering static component then anything works just fine.

coder321 commented 6 years ago

How to fix it?

coder321 commented 6 years ago

I fix it ,set the array length >1

uuau99999 commented 6 years ago

@coder321 I have tried using an array length of 2 but the active dot still can't behave correctly.

MariusMeiners commented 6 years ago

try key={this.state.dynamicContent.length} on Swiper.

                        <Swiper
                        key={this.state.productImages.length}
                        style={styles.swiper}
                        >
                            {swiperItems}
                        </Swiper>

Also give your items a key. my .map() looks like this:

        const swiperItems = this.state.productImages.map(item => {
            return(
                    <Image 
                    source={{uri: item.realpath}}
                    style={styles.swiperimage}
                    key={item.position}
                    />
            )
        })
uuau99999 commented 6 years ago

@MariusMeiners Thanks. I will check that out later.

amestsantim commented 6 years ago

Yes, indeed setting the key prop of the swiper to the length of the array to be mapped over seems to solve the problem Thanks @MariusMeiners

welcome2github commented 6 years ago

知道是问什么吗, 虽然解决了,但是不明白原因

thiszhong commented 6 years ago

@MariusMeiners Thanks a lot, that is effective. And do you know why?

MariusMeiners commented 6 years ago

@wJianZhong I think at the time i came up with an explanation that made sense but I already forgot again :D, sorry !

thiszhong commented 6 years ago

@MariusMeiners That's all right, at least the problem has resolved. So thanks again (●’◡’●)

sunnylqm commented 6 years ago

@MariusMeiners @wJianZhong This is beacuse swiper does not update dots correctly when children changes. Set a key and change the key later will force any component to re-render again hence update the dots. Set the key to the array length is a very smart way so the swiper will only re-render if the array length changes.

thiszhong commented 6 years ago

@sunnylqm Agreed! I just had a misconception that the swiper will re-render it all when children changed.

huanghaiyang commented 6 years ago

添加如下代码到onScrollEnd方法的最后: this.props.onIndexChanged && this.props.onIndexChanged(e.nativeEvent.contentOffset.x / Dimensions.get('window').width);

djpetenice commented 6 years ago

So this solution worked for my Android app. I'm now working on the iOS version and although this method works for the pagination, when I update the content in the swiper it seems to move to the last slide in the list before the new content loads in - and does the same for the incoming content. If I remove the key this problem goes but the pagination screws up.

djpetenice commented 6 years ago

Its seems that setting state elsewhere is causing these issues for me.

guoliang1206 commented 6 years ago

not works with key

 <Swiper loadMinimal loadMinimalSize={2} style={{flex:1}} loop={false} key={this.params.data.length}>
                        {this.params.data.map((item,i) => {
                            return(
                                <NetWorkImage
                                    url={item}
                                    defaultStyle={{flex:4,width:screenW,height:screenW}}
                                    key={i}
                                />
                            )
                        })}
                    </Swiper>
HighSoftWare96 commented 5 years ago

I've solved with this workaround: Removing the setState onComponentWillReceiveProps fixes the bug for me.

  componentWillReceiveProps(nextProps) {
    if (!nextProps.autoplay && this.autoplayTimer)
      clearTimeout(this.autoplayTimer);
    /*this.setState(
      this.initState(nextProps, this.props.index !== nextProps.index)
    );*/
  }

I think that the problem is that every time the component updates it is reset.

udarts commented 5 years ago

I've solved with this workaround: Removing the setState onComponentWillReceiveProps fixes the bug for me.

  componentWillReceiveProps(nextProps) {
    if (!nextProps.autoplay && this.autoplayTimer)
      clearTimeout(this.autoplayTimer);
    /*this.setState(
      this.initState(nextProps, this.props.index !== nextProps.index)
    );*/
  }

I think that the problem is that every time the component updates it is reset.

Many thanks, that solved an issue I had as well. For me I used the slider as card to show messages, and when swiping, it marks the messages as read. It wasn't working correctly, until I commented out that specific line.

Cheers,

Purecoder commented 5 years ago

not works with key

 <Swiper loadMinimal loadMinimalSize={2} style={{flex:1}} loop={false} key={this.params.data.length}>
                        {this.params.data.map((item,i) => {
                            return(
                                <NetWorkImage
                                    url={item}
                                    defaultStyle={{flex:4,width:screenW,height:screenW}}
                                    key={i}
                                />
                            )
                        })}
                    </Swiper>

this works for me. Thanks.

JPeer264 commented 5 years ago

Could this be the same solution / problem: https://github.com/leecade/react-native-swiper/issues/919#issuecomment-454336046 ?

reetika-2 commented 5 years ago

not works with key

 <Swiper loadMinimal loadMinimalSize={2} style={{flex:1}} loop={false} key={this.params.data.length}>
                        {this.params.data.map((item,i) => {
                            return(
                                <NetWorkImage
                                    url={item}
                                    defaultStyle={{flex:4,width:screenW,height:screenW}}
                                    key={i}
                                />
                            )
                        })}
                    </Swiper>

this works for me. Thanks.

Thanks, this works.

kevindragong commented 5 years ago

Thanks, this works.

Thanks, this works.

SohailYaseenBhutto commented 4 years ago

@MariusMeiners Thanks, its working. But how!!! even though "key" is not used in library.

Sohailbhutto commented 4 years ago

@MariusMeiners Thanks, its working. But how!!! even though "key" is not used in library.

satish1020 commented 3 years ago

key={this.state.dynamicContent.length} is working well for me