I’m facing an issue with updating the content of cards in a swiper using react-native-deck-swiper
. I have a button external to the swiper, and when pressing it I want to update the content of the current card and trigger a re-render to reflect the changes.
I’ve managed to update the state of the item correctly, but the card doesn’t re-render immediately. It only renders again when I start swiping the item.
The documentation suggests a possible fix, stating, “A possible fix for the situation is setting the cardIndex
on the parent component whenever deck re-renders are needed.” However, my attempt to implement this hasn’t been successful.
I have noticed that the change is render when the overlay condition are required (even if no overlay is set).
Below is a reproducible example of the problem :
import React, { useRef, useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import Swiper from 'react-native-deck-swiper';
const cards = [
{ color: 'red', updated: false },
{ color: 'blue', updated: false },
{ color: 'green', updated: false },
{ color: 'yellow', updated: false },
{ color: 'purple', updated: false },
];
export default function App() {
const [cardIndex, setCardIndex] = useState(0);
const swiperRef = useRef(null);
const updateCard = () => {
cards[cardIndex].updated = !cards[cardIndex].updated;
// Force re-render??
setCardIndex(cardIndex);
};
const onSwiped = () => {
setCardIndex((cardIndex + 1) % cards.length);
};
const renderCard = (card) => (
<View style={[styles.card, { backgroundColor: card.color }]}>
{card.updated && <Text style={styles.updatedText}>UPDATED</Text>}
</View>
);
return (
<View style={styles.container}>
<Swiper
ref={swiperRef}
cards={cards}
renderCard={renderCard}
onSwiped={onSwiped}
onSwipedLeft={onSwiped}
onSwipedRight={onSwiped}
cardIndex={cardIndex}
infinite
/>
<TouchableOpacity style={styles.button} onPress={updateCard}>
<Text style={styles.buttonText}>Update card</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f7f7f7',
alignItems: 'center',
justifyContent: 'center',
},
card: {
width: '80%',
height: '80%',
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'center',
},
updatedText: {
position: 'absolute',
fontSize: 24,
fontWeight: 'bold',
color: 'black',
},
button: {
position: 'absolute',
bottom: 20,
padding: 10,
backgroundColor: 'blue',
borderRadius: 5,
},
buttonText: {
color: 'white',
fontSize: 16,
},
});
I’d appreciate any insights on how to solve this issue and get the card to re-render immediately upon pressing the button. Thank you!
Alexandre is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.