Amine
Amine

Reputation: 2434

How to re-render React Native Web Swiper based on State change?

I am using this package to create a Swiper in React Native. I used static data and it is working, but now I'm fetching data from server and save it in the state as an Array. The problem is when mapping the data inside the swiper to create dynamic sliders, it is not showing anything, but if I do it outside of the Swiper it is rendering.

How can I solve this problem?

 <Swiper
    from={0}
    minDistanceForAction={0.1}
    controlsProps={{
        dotsTouchable: true,
        prevPos: 'left',
        nextPos: 'right',
        nextTitle: '',
        prevTitle: '',
        dotsWrapperStyle: { marginTop: ScaleHelpers.CalcHeight(8), width: ScaleHelpers.CalcWidth(7), height: ScaleHelpers.CalcHeight(7), borderRadius: ScaleHelpers.CalcWidth(7) },
                                dotActiveStyle: { width: ScaleHelpers.CalcWidth(7), height: ScaleHelpers.CalcHeight(7), borderRadius: ScaleHelpers.CalcWidth(7) },
                            }}
 >

 {
   this.state.notifications.map((notif, index) => {
      return (
          <View style={[styless.slideContainer]}>

                                            <Card transparent style={{
                                                flex: 0,
                                                elevation: 3,
                                                shadowColor: "#000",
                                                shadowOpacity: 0.1,
                                                shadowOffset: { width: 0, height: 2 },
                                                shadowRadius: 1.0,

                                            }}>
                                                <CardItem
                                                    style={{ paddingTop: ScaleHelpers.CalcHeight(14), paddingLeft: ScaleHelpers.CalcWidth(14), paddingBottom: ScaleHelpers.CalcHeight(14) }}
                                                >
                                                    <Left>
                                                        <View style={{
                                                            width: ScaleHelpers.CalcWidth(60),
                                                            height: ScaleHelpers.CalcHeight(60),
                                                            borderRadius: ScaleHelpers.CalcWidth(60) / 2,
                                                            margin: 0,
                                                            padding: 0,
                                                            justifyContent: 'center',
                                                            backgroundColor: '#FF004E',
                                                            elevation: 5,
                                                            shadowColor: "#000",
                                                            shadowOpacity: 0.1,
                                                            shadowOffset: { width: 0, height: ScaleHelpers.CalcHeight(2) },
                                                            shadowRadius: 1.0,
                                                        }}>
                                                            <Image source={bmwerror} style={{ alignSelf: 'center' }} />
                                                        </View>
                                                        <Body style={{ marginLeft: ScaleHelpers.CalcWidth(23) }}>
                                                            <Text style={styles.cardUpperText}>{notif.msg}</Text>
                                                            <Text style={styles.cardLowerText}>{notif.axle}{notif.side}</Text>
                                                        </Body>
                                                    </Left>
                                                </CardItem>
                                            </Card>

                                        </View>
      )
   })

 }
</Swiper>

Upvotes: 1

Views: 1593

Answers (1)

Anus Kaleem
Anus Kaleem

Reputation: 564

From the documentation of the module:

Dynamic content The Swiper will not be re-rendered if slides state or props have changed. Slides must control their condition.

This means that you have to manage state change on your own through your slides and not through Swiper component.

EDIT:

So, you can create a custom Slide module to handle those slides coming from server as:

class Slide extends React.Component {
constructor(props) {
    super(props);
    // your state for the slide component goes here....
}
render() {
    const { msg, axle, side } = this.props.notification; // destructure your notification prop being passed from the map method of parent component
    return (
        <View style={[styless.slideContainer]}>
            <Card transparent style={{
                flex: 0,
                elevation: 3,
                shadowColor: "#000",
                shadowOpacity: 0.1,
                shadowOffset: { width: 0, height: 2 },
                shadowRadius: 1.0,

            }}>
                <CardItem
                    style={{ paddingTop: ScaleHelpers.CalcHeight(14), paddingLeft: ScaleHelpers.CalcWidth(14), paddingBottom: ScaleHelpers.CalcHeight(14) }}
                >
                    <Left>
                        <View style={{
                            width: ScaleHelpers.CalcWidth(60),
                            height: ScaleHelpers.CalcHeight(60),
                            borderRadius: ScaleHelpers.CalcWidth(60) / 2,
                            margin: 0,
                            padding: 0,
                            justifyContent: 'center',
                            backgroundColor: '#FF004E',
                            elevation: 5,
                            shadowColor: "#000",
                            shadowOpacity: 0.1,
                            shadowOffset: { width: 0, height: ScaleHelpers.CalcHeight(2) },
                            shadowRadius: 1.0,
                        }}>
                            <Image source={bmwerror} style={{ alignSelf: 'center' }} />
                        </View>
                        <Body style={{ marginLeft: ScaleHelpers.CalcWidth(23) }}>
                            {/* use your destructure constants where required */}
                            <Text style={styles.cardUpperText}>{msg}</Text> 
                            <Text style={styles.cardLowerText}>{axle}{side}</Text>
                        </Body>
                    </Left>
                </CardItem>
            </Card>

        </View>
    );
}
}export default Slide;

I have mentioned in comments how you can take the required information out of the notifications object. Now comes the sending part, in your map function just call your newly created Slide component and pass the notification object as a prop like this:

<Slide notification={notif}/>

Notice here, in notification={notif} notification would serve as the name of the prop in Slide component and there you have to extract information from this.props.notification object as mentioned earlier.

Upvotes: 1

Related Questions