New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
uuau99999 opened this Issue Jan 30, 2018 · 18 comments

Comments

Projects
None yet
@uuau99999

uuau99999 commented Jan 30, 2018

Which OS ?

IOS 11.2 / android 7.0

Version

Which versions are you using:

  • react-native-swiper v1.5.13?
  • react-native v0.52.1?

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

This comment has been minimized.

coder321 commented Feb 1, 2018

How to fix it?

@coder321

This comment has been minimized.

coder321 commented Feb 1, 2018

I fix it ,set the array length >1

@uuau99999

This comment has been minimized.

uuau99999 commented Feb 1, 2018

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

@MariusMeiners

This comment has been minimized.

MariusMeiners commented Feb 5, 2018

try
key={this.state.dynamicContent.length}
on Swiper. Solved the issue for me for some reason....

                        <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

This comment has been minimized.

uuau99999 commented Feb 6, 2018

@MariusMeiners Thanks. I will check that out later.

@amestsantim

This comment has been minimized.

amestsantim commented Feb 10, 2018

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

This comment has been minimized.

welcome2github commented Mar 29, 2018

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

@thiszhong

This comment has been minimized.

thiszhong commented Apr 17, 2018

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

@MariusMeiners

This comment has been minimized.

MariusMeiners commented Apr 18, 2018

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

@thiszhong

This comment has been minimized.

thiszhong commented Apr 20, 2018

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

@sunnylqm

This comment has been minimized.

Collaborator

sunnylqm commented May 16, 2018

@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

This comment has been minimized.

thiszhong commented May 16, 2018

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

@huanghaiyang

This comment has been minimized.

huanghaiyang commented Jun 10, 2018

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

@djpetenice

This comment has been minimized.

djpetenice commented Jul 5, 2018

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

This comment has been minimized.

djpetenice commented Jul 6, 2018

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

@guoliang1206

This comment has been minimized.

guoliang1206 commented Sep 17, 2018

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

This comment has been minimized.

HighSoftWare96 commented Nov 9, 2018

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

This comment has been minimized.

udarts commented Nov 17, 2018

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,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment