Animated.FlatList is broken
See original GitHub issueDescription
Button in FlatList is not pressable after the element is unmounted. Kinda hard to explain verbally, please take a look at the video below. Interestingly, if you used Animated.FlatList before, and swap it back to regular FlatList, the regular FlatList will be affected as well. You need to restart the bundler to resolve the problem.
Expected behavior
Pressable in next element should be pressable after the previous element is removed.
Actual behavior & steps to reproduce
As you can see in the video, after deleting one element, the Pressable in next element is not pressable.
Snack or minimal code example
diff between these implementation is within the FlatList only
React Native's FlatList implementation
import React, {useState} from 'react';
import {
Button,
View,
Text,
FlatList,
TextInput,
SafeAreaView,
} from 'react-native';
function Participant({name, onRemove, id}) {
return (
<View style={[styles.participantView]}>
<Text>{`${name};${id}`}</Text>
<Button title="Remove" color="red" onPress={onRemove} />
</View>
);
}
const App = () => {
const [inputValue, setInputValue] = useState('Reanimated');
const [participantList, setParticipantList] = useState([]);
const addParticipant = () => {
setParticipantList(
[{name: inputValue, id: Date.now().toString()}].concat(participantList),
);
};
const renderParticipant = React.useCallback(({item: participant}) => {
const removeParticipant2 = () => {
setParticipantList(prev => {
return prev.filter(prevPar => prevPar.id !== participant.id);
});
};
return (
<Participant
key={participant.id + 'FLATLIST'}
id={participant.id}
name={participant.name}
onRemove={removeParticipant2}
/>
);
}, []);
return (
<SafeAreaView style={{flex: 1, width: '100%'}}>
<View style={styles.listView}>
<Text>FlatList</Text>
<FlatList
data={participantList}
style={[{width: '100%'}]}
renderItem={renderParticipant}
/>
</View>
<View style={[styles.bottomRow]}>
<View style={[styles.textInput]}>
<Text>Add participant: </Text>
<TextInput
placeholder="Name"
value={inputValue}
onChangeText={setInputValue}
/>
</View>
<Button
title="Add"
disabled={inputValue === ''}
onPress={addParticipant}
/>
</View>
</SafeAreaView>
);
};
const styles = {
participantView: {
borderBottomColor: 'black',
flex: 1,
borderBottomWidth: 1,
padding: 10,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#fffbeb',
},
listView: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
},
bottomRow: {
width: '100%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 10,
},
textInput: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
},
};
export default App;
Problematic Animated.FlatList implementation
import React, {useState} from 'react';
import {Button, View, Text, TextInput, SafeAreaView} from 'react-native';
import Animated, {
Layout,
LightSpeedInLeft,
LightSpeedOutLeft,
} from 'react-native-reanimated';
function Participant({name, onRemove, id}) {
return (
<Animated.View
style={[styles.participantView]}
entering={LightSpeedInLeft}
exiting={LightSpeedOutLeft}
layout={Layout.springify()}>
<Text>{`${name};${id}`}</Text>
<Button title="Remove" color="red" onPress={onRemove} />
</Animated.View>
);
}
const App = () => {
const [inputValue, setInputValue] = useState('Reanimated');
const [participantList, setParticipantList] = useState([]);
const addParticipant = () => {
setParticipantList(
[{name: inputValue, id: Date.now().toString()}].concat(participantList),
);
};
const renderParticipant = React.useCallback(({item: participant}) => {
const removeParticipant2 = () => {
setParticipantList(prev => {
return prev.filter(prevPar => prevPar.id !== participant.id);
});
};
return (
<Participant
key={participant.id + 'FLATLIST'}
id={participant.id}
name={participant.name}
onRemove={removeParticipant2}
/>
);
}, []);
return (
<SafeAreaView style={{flex: 1, width: '100%'}}>
<View style={styles.listView}>
<Text>Animated.FlatList</Text>
<Animated.FlatList
itemLayoutAnimation={Layout.springify()}
data={participantList}
style={[{width: '100%'}]}
renderItem={renderParticipant}
/>
</View>
<View style={[styles.bottomRow]}>
<View style={[styles.textInput]}>
<Text>Add participant: </Text>
<TextInput
placeholder="Name"
value={inputValue}
onChangeText={setInputValue}
/>
</View>
<Button
title="Add"
disabled={inputValue === ''}
onPress={addParticipant}
/>
</View>
</SafeAreaView>
);
};
const styles = {
participantView: {
borderBottomColor: 'black',
flex: 1,
borderBottomWidth: 1,
padding: 10,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#fffbeb',
},
listView: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
},
bottomRow: {
width: '100%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 10,
},
textInput: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
},
};
export default App;
Package versions
- React Native: 0.66.3
- React Native Reanimated: 2.3
- NodeJS:
- Xcode:
- Java & Gradle:
Affected platforms
- Android
- iOS (not sure)
- Web (not sure)
Issue Analytics
- State:
- Created 2 years ago
- Reactions:11
- Comments:15 (2 by maintainers)
Top Results From Across the Web
react native flatlist animation is not working as expected on ...
I'm working in app that needs flatlist animation with RTL devices. I built a small app to understand how it will work.
Read more >Animated FlatList in React Native (Reanimated) - YouTube
What's up mobile devs? Today we're going to build from scratch a super powerful and simple animation over the React Native FlatList ......
Read more >FlatList Animations in React Native with Reanimated 2
In this tutorial, we will implement FlatList animations in React Native, inspired by iOS 16 notifications, using the library Reanimated 2.
Read more >FlatList - React Native
scrollToIndex() · 'animated' (boolean) - Whether the list should do an animation while scrolling. · 'index' (number) - The index to scroll...
Read more >React Native FlatList - Getting Your React Native Basics Right
import * as React from 'react'; import { FlatList, Text, View, StyleSheet } from 'react-native'; # A component to render individual item const ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

This issue happens without
Animated.Flatlistwith a normalFlatListI narrowed it down to usingAnimated.Viewinstead a normalFlatListSo it doesn’t have anything to do with
Animated.Flatlistand even layout prop.Also tested on iOS and it works fine there.
just removing the
enteringmakes it also work on android.Created another issue with minimal example feel free to test : https://github.com/software-mansion/react-native-reanimated/issues/3029
This even happens when i just use an Animated.View with one of the default layoutanimations anywhere on my screen. As soon as i do that “ghost” views stick around on Android. Like the ListEmptyComponent for instance.