Issue
I am currently developing a social media-like mobile app using React Native. In this app, I'm utilizing two key components: FlashList from @shopify/flash-list for rendering posts and react-native-video for handling video playback. However, I've encountered a problematic behavior where the react-native-video component refreshes every time I update a state using Zustand. This constant refreshing issue not only causes a significant performance drop but also leads to crashes on Android devices.
Code Structure
Here's an overview of my code structure:
// Other imports...
import { FlashList } from '@shopify/flash-list'
// Other imports...
// Component
import SocialContents from '../../components/Recognition/Contents'
// Zustand Store
import useSocialWallStore from '../../store/useSocialWallStore'
const XXX = ({ props, route }) => {
const { getSocialWallContent, socialWallContents } =
useSocialWallStore((state) => state)
const generateNewData = () => {
// Generate new data...
}
// Other code...
const SocialContentsMemo = React.memo(SocialContents)
const wallData = socialWallContents?.contents.sort(
(a, b) => Date.parse(b.dateCreatedUtc) - Date.parse(a.dateCreatedUtc),
)
return (
<SafeAreaView style={{ flex: 1, backgroundColor: "white" }}>
{/* Other codes here... */}
<View
style={{
height: Dimensions.get("screen").height,
width: Dimensions.get("screen").width,
}}
>
<FlashList
estimatedItemSize={
// This is the total data...
}
onEndReached={() => generateNewData()}
onEndReachedThreshold={0.1}
scrollEventThrottle={50}
keyboardShouldPersistTaps="handled"
contentContainerStyle={{
paddingHorizontal: 18,
paddingBottom: 225,
paddingTop: 0,
}}
data={wallData}
keyExtractor={(_, index) => index.toString()}
renderItem={({ item, index }) => (
<View key={index}>
<SocialContentsMemo data={item} onDelete={onDelete} />
</View>
)}
ListFooterComponent={() =>
socialWallContents?.loadingMore && (
<View className="w-full items-center justify-center py-4">
<ActivityIndicator color={'black'} size="large" />
</View>
)
}
/>
</View>
{/* Other codes here... */}
</SafeAreaView>
);
}
export default XXX
Additionally, here's how I display the video within the SocialContents component:
{data?.mediaUrl && (
<View className="relative w-full py-1">
{['.mp4', '.webm', '.avi', '.mov', '.mkv', '.flv'].some(
(format) => data.mediaUrl.endsWith(format),
) ? (
<>
<Video
source={{ uri: data.mediaUrl }}
style={{ width: '100%', height: 200 }}
resizeMode="contain"
controls={isBuffered}
paused={true}
onLoad={() => setIsBuffered(true)}
/>
{!isBuffered && (
<ActivityIndicator
className="absolute left-[50%] top-[50%]"
size="large"
/>
)}
</>
) : ['jpg', '.jpeg', '.png', '.gif'].some((format) =>
data.mediaUrl.endsWith(format),
) ? (
// For displaying images...
) : ['mp3', '.wav', '.ogg'].some((format) =>
data.mediaUrl.endsWith(format),
) ? (
// For handling audio...
) : null}
</View>
)}
Version/Package:
"react-native-video": "^5.2.1",
"@shopify/flash-list": "^1.6.1",
"zustand": "^4.0.0",
"react-native": "0.69.4",
"react": "18.0.0",
If you have any questions or need further assistance with this issue, please feel free to ask.
I solved it using a callback
Solution: