Skip to content

Commit 1b770db

Browse files
committed
Reinstate rendering hack
1 parent 214d7da commit 1b770db

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

src/components/common/EdgeCarousel.tsx

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React, { useState } from 'react'
2-
import { ListRenderItem, View } from 'react-native'
2+
import { InteractionManager, ListRenderItem, Platform, View } from 'react-native'
33
import Carousel, { Pagination } from 'react-native-snap-carousel'
44

5+
import { useAsyncEffect } from '../../hooks/useAsyncEffect'
56
import { useHandler } from '../../hooks/useHandler'
67
import { cacheStyles, Theme, useTheme } from '../services/ThemeContext'
78

@@ -26,16 +27,47 @@ export function EdgeCarousel<T>(props: Props<T>): JSX.Element {
2627
const carouselRef = React.useRef<Carousel<any>>(null)
2728

2829
const [activeIndex, setActiveIndex] = useState(0)
30+
const [dataLocal, setDataLocal] = useState(data)
31+
32+
React.useEffect(() => {
33+
setDataLocal(data)
34+
}, [data])
2935

3036
const renderItem = useHandler<ListRenderItem<T>>(info => (
3137
<View style={[styles.childContainer, { width: width * 0.9, height }]}>{props.renderItem(info)}</View>
3238
))
3339

40+
/**
41+
* Carousel's FlatList bug workaround. Fixes the issue where items are
42+
* hidden until scroll actions are performed either in the carousel or on the
43+
* scene itself.
44+
*/
45+
useAsyncEffect(
46+
async () => {
47+
// HACK: With 1 item, this is the only way to force a render in iOS
48+
if (Platform.OS === 'ios' && dataLocal.length === 1) {
49+
const tempData = [...dataLocal]
50+
setDataLocal([])
51+
setTimeout(() => {
52+
setDataLocal(tempData)
53+
}, 500)
54+
}
55+
// The built-in hack fn works for all other cases
56+
else if (carouselRef.current != null) {
57+
await InteractionManager.runAfterInteractions(() => {
58+
carouselRef.current?.triggerRenderingHack()
59+
})
60+
}
61+
},
62+
[dataLocal], // Depend on dataLocal instead of data to avoid infinite loops
63+
'triggerRenderingHack'
64+
)
65+
3466
return (
3567
<View style={styles.carouselContainer}>
3668
<Carousel
3769
ref={carouselRef}
38-
data={data}
70+
data={dataLocal}
3971
keyExtractor={keyExtractor}
4072
renderItem={renderItem}
4173
sliderWidth={width}
@@ -55,7 +87,7 @@ export function EdgeCarousel<T>(props: Props<T>): JSX.Element {
5587
marginTop: -theme.rem(1),
5688
marginBottom: -theme.rem(1)
5789
}}
58-
dotsLength={data.length}
90+
dotsLength={dataLocal.length}
5991
activeDotIndex={activeIndex}
6092
tappableDots={carouselRef.current != null}
6193
dotStyle={styles.dotStyle}

0 commit comments

Comments
 (0)