react-native-snap-carousel
react-native-snap-carousel copied to clipboard
RenderItem doesn't refresh when state change
Is this a bug report, a feature request, or a question?
A bug report
Have you followed the required steps before opening a bug report?
- [X] I have read the guidelines regarding bug report.
- [X] I have reviewed the documentation in its entirety, including the dedicated documentations :books:.
- [X] I have searched for existing issues and made sure that the problem hasn't already been reported.
- [X] I am using the latest plugin version.
- [X] I am following the issue template closely in order to produce a useful bug report.
Have you made sure that it wasn't a React Native bug?
it's not a react native bug.
Is the bug specific to iOS or Android? Or can it be reproduced on both platforms?
I just test to Android.
Is the bug reproductible in a production environment (not a debug one)?
I don't use it to prod. I check in my phone with react-native run-android.
Environment
Environment: React: 16.8.6 React native: 0.60.5 react-native-snap-carousel: 3.8.2
Target Platform: Android (6.0)
Expected Behavior
I have 3 items. Each item is a button that opens the camera. Once we take the picture, it should show the picture instead of the button for each item.
Actual Behavior
When I take the photo, it updates the state but it does not display the photo.
Reproducible Demo
<Carousel
ref={(c) => { this._carousel = c; }}
data={[
{key: 0, urlImage: this.state.urlImage1,},
{key: 1, urlImage: this.state.urlImage2,},
{key: 2, urlImage: this.state.urlImage3,},
]}
extraData={this.state}
renderItem={this._renderItem}
sliderWidth={screen.width}
sliderHeight={300}
itemWidth={300}
itemHeight={300}
containerCustomStyle={{
flexGrow: 0,
}}
/>
_renderItem ({item, index}) {
return (
<View style={{ width: 300, height: 300, position: "relative", marginTop: 20 }}>
{ item.urlImage == "data:image/jpeg;base64" ?
<TouchableOpacity
onPress={(e) => this.takePhoto(e, item.urlImage)}
style={{ backgroundColor: 'transparent', borderColor: 'white', borderWidth: 1 ,width: 300, height: 300, zIndex: 9999, elevation: 9999, position: "absolute", top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center' }}
>
<View>
<Icon
type="MaterialIcons"
name="add-a-photo"
size={95}
color={"white"}
/>
</View>
</TouchableOpacity>
: <View></View>
}
<Image
source={{ uri : item.urlImage }}
style={{ width: 300, height: 300, backgroundColor: "#046381" }}
/>
</View>
);
}
takePhoto(e, item) {
ImagePicker.launchCamera(options, (response) => {
if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else {
const source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
[item]: source.uri,
refresh: !this.state.refresh
}, () => { console.log(this.state.refresh) });
}
})
}
I have an issue with updating the state in component.
In my case, I am changing the width of the sliderWidth and itemWidth when the layout of the container view changes.
In a first moment the carousel re-render it self, but it doesn´t always apply.
Hi. I don't know if you've solved the problem, but I had the same problem today. If you do as in the example below, the high probability of the problem will be solved. I hope it helps.
state = { refresh: false, };
<Carousel ref={(c) => { this._carousel = c; }} data={[ {key: 0, urlImage: this.state.urlImage1,}, {key: 1, urlImage: this.state.urlImage2,}, {key: 2, urlImage: this.state.urlImage3,}, ]} extraData={this.state.refresh} renderItem={this._renderItem} sliderWidth={screen.width} sliderHeight={300} itemWidth={300} itemHeight={300} containerCustomStyle={{ flexGrow: 0, }} />
takePhoto(e, item) { ImagePicker.launchCamera(options, (response) => { if (response.error) { console.log('ImagePicker Error: ', response.error); } else { const source = { uri: 'data:image/jpeg;base64,' + response.data }; this.setState({ [item]: source.uri, refresh: !this.state.refresh }, () => { console.log(this.state.refresh) }); this.setState({ refresh: !refresh}); } }) }
@kasim444 extraData
props is available?
up! currently having problems refreshing the component as well! Any clue on how to force refresh?
Any news about this?
Also having this issue. I have the carousel sitting over a map screen and when users zoom out or changes the map view, the data set is then altered. This causes an issue with the scroll behavior of the carousel and prevents it from scrolling.
Still not working ...
I solved this by doing a setTimeOut and forcing a re-render of the whole page by toggling my isLoading state element. It's not the best solution, but it works:
` componentDidUpdate = () => {
if (
JSON.stringify(this.props.unsavedItem.images) !==
JSON.stringify(this.state.carouselData)
) {
this.setState({
carouselData: this.props.unsavedItem.images,
isLoading: true,
});
// Weird hack to fix the missing image because
// Carousel doesn't refresh when changing images
setTimeout(() => {
this.setState({ isLoading: false });
}, 150);
}
};`
Of course you need to have your main content toggled by your isLoading.
Sorry, please allow me to advertise for my open source library! ~ I think this library react-native-reanimated-carousel will solve your problem. It is a high performance and very simple component, complete with React-Native reanimated 2
You can try use triggerRenderingHack()
.
useEffect( () => {
carouselRef.current.triggerRenderingHack();
}, [ items ] );
...
<Carousel
ref={carouselRef}
data={items}
renderItem={renderItem}
onSnapToItem={_setCarouselIndex}
sliderWidth={screenWidth}
itemWidth={screenWidth}
/>