AnimatedFlashList is an animated version of FlashList created using React Native’s Animated.createAnimatedComponent. It supports all the same props as FlashList while allowing you to use it with React Native’s Animated API.
Usage
import { Animated } from "react-native";
import AnimatedFlashList from "@shopify/flash-list/dist/AnimatedFlashList";
function MyAnimatedList() {
const scrollY = useRef(new Animated.Value(0)).current;
return (
<AnimatedFlashList
data={items}
renderItem={({ item }) => <ItemView item={item} />}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{ useNativeDriver: true }
)}
scrollEventThrottle={16}
/>
);
}
Common Use Cases
Create a header that fades out or changes size based on scroll position:
import { Animated, StyleSheet } from "react-native";
import AnimatedFlashList from "@shopify/flash-list/dist/AnimatedFlashList";
function ListWithAnimatedHeader() {
const scrollY = useRef(new Animated.Value(0)).current;
const headerOpacity = scrollY.interpolate({
inputRange: [0, 100],
outputRange: [1, 0],
extrapolate: "clamp",
});
const headerHeight = scrollY.interpolate({
inputRange: [0, 100],
outputRange: [80, 50],
extrapolate: "clamp",
});
return (
<>
<Animated.View
style={[
styles.header,
{
opacity: headerOpacity,
height: headerHeight,
},
]}
>
<Text>Animated Header</Text>
</Animated.View>
<AnimatedFlashList
data={items}
renderItem={({ item }) => <ItemView item={item} />}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{ useNativeDriver: false } // false for layout properties
)}
scrollEventThrottle={16}
/>
</>
);
}
const styles = StyleSheet.create({
header: {
position: "absolute",
top: 0,
left: 0,
right: 0,
backgroundColor: "white",
zIndex: 1,
justifyContent: "center",
alignItems: "center",
},
});
Parallax Effect
Implement a parallax scrolling effect:
import { Animated } from "react-native";
import AnimatedFlashList from "@shopify/flash-list/dist/AnimatedFlashList";
function ParallaxList() {
const scrollY = useRef(new Animated.Value(0)).current;
const bannerTranslateY = scrollY.interpolate({
inputRange: [0, 300],
outputRange: [0, -150],
extrapolate: "clamp",
});
return (
<>
<Animated.Image
source={{ uri: "https://example.com/banner.jpg" }}
style={[
styles.banner,
{
transform: [{ translateY: bannerTranslateY }],
},
]}
/>
<AnimatedFlashList
data={items}
renderItem={({ item }) => <ItemView item={item} />}
contentContainerStyle={{ paddingTop: 200 }}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{ useNativeDriver: true }
)}
scrollEventThrottle={16}
/>
</>
);
}
const styles = StyleSheet.create({
banner: {
position: "absolute",
top: 0,
left: 0,
right: 0,
height: 200,
},
});
Show a progress bar based on scroll position:
import { Animated, Dimensions } from "react-native";
import AnimatedFlashList from "@shopify/flash-list/dist/AnimatedFlashList";
function ListWithProgress() {
const scrollY = useRef(new Animated.Value(0)).current;
const [contentHeight, setContentHeight] = useState(0);
const [listHeight, setListHeight] = useState(0);
const scrollableHeight = contentHeight - listHeight;
const progressWidth = scrollY.interpolate({
inputRange: [0, scrollableHeight],
outputRange: [0, Dimensions.get("window").width],
extrapolate: "clamp",
});
return (
<>
<Animated.View
style={[
styles.progressBar,
{ width: progressWidth },
]}
/>
<AnimatedFlashList
data={items}
renderItem={({ item }) => <ItemView item={item} />}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{ useNativeDriver: false }
)}
onContentSizeChange={(_, height) => setContentHeight(height)}
onLayout={(e) => setListHeight(e.nativeEvent.layout.height)}
scrollEventThrottle={16}
/>
</>
);
}
const styles = StyleSheet.create({
progressBar: {
position: "absolute",
top: 0,
left: 0,
height: 3,
backgroundColor: "blue",
zIndex: 1,
},
});
Props
AnimatedFlashList accepts all the same props as FlashList, plus any props that work with animated components.
Additional Animated Props
When using AnimatedFlashList, you can animate the following additional props:
contentContainerStyle - Animate the content container style
style - Animate the list container style
- Any other style properties that support animation
Ref Methods
AnimatedFlashList exposes the same ref methods as FlashList.
const listRef = useRef<FlashListRef<ItemType>>(null);
<AnimatedFlashList ref={listRef} data={data} renderItem={renderItem} />
// All FlashList ref methods are available:
listRef.current?.scrollToIndex({ index: 5, animated: true });
listRef.current?.scrollToEnd({ animated: true });
Use Native Driver When Possible
For best performance, use useNativeDriver: true when animating transform and opacity properties:
<AnimatedFlashList
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{ useNativeDriver: true } // ✅ Good for transform/opacity
)}
/>
Set useNativeDriver: false when animating layout properties like width, height, padding, or margin. These cannot be animated on the native thread.
Use scrollEventThrottle to control how often scroll events fire:
<AnimatedFlashList
scrollEventThrottle={16} // ~60fps
onScroll={handleScroll}
/>
Lower values (like 16) provide smoother animations but may impact performance. Higher values (like 100) are more performant but may appear choppy.
Avoid Complex Interpolations
Complex interpolations can impact performance. Keep interpolation logic simple:
// ✅ Good - simple interpolation
const opacity = scrollY.interpolate({
inputRange: [0, 100],
outputRange: [1, 0],
});
// ❌ Avoid - complex calculation in interpolation
const complexValue = scrollY.interpolate({
inputRange: [0, 50, 100, 150, 200],
outputRange: [0, 25, 75, 100, 125],
});
Type Safety
AnimatedFlashList is fully typed and supports the same generics as FlashList:
interface Item {
id: string;
title: string;
}
// Type-safe AnimatedFlashList
<AnimatedFlashList<Item>
data={items}
renderItem={({ item }) => (
<Text>{item.title}</Text> // item is typed as Item
)}
keyExtractor={(item) => item.id} // item is typed as Item
/>
Differences from FlatList
Just like FlashList, AnimatedFlashList has some key differences from React Native’s Animated.FlatList:
- Better recycling: Items are recycled more efficiently, which is especially important for animated lists
- Consistent performance: Animation performance remains stable even with large datasets
See the FlashList documentation for more details on these differences.
Implementation Details
AnimatedFlashList is created using React Native’s Animated.createAnimatedComponent:
const AnimatedFlashList = Animated.createAnimatedComponent<
React.ComponentType<FlashListProps<any>>
>(FlashList);
This means it supports all Animated API features including:
Animated.Value
Animated.event
Animated.interpolate
- Animated style props
- Animated refs