react-navigation / react-navigation/react-navigation
[Android] Conditional views flicker when `react-native-reanimated` is imported
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 24.5k
- Forks
- 5.1k
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 18
Description
Current behavior
In a fresh expo install (46.0.16), when using conditional state to switch what renders, the page will flicker when testing in Android emulator if react-native-reanimated is imported (the two views overlap).
Note: While I have provided a Snack, it cannot be reproduced there as the flicker happens too quickly for the Snack render. You must run the code locally in Android Emulator.
If you slow down the following video you will be able to see the issue more easily. Towards the end of the video I comment out the react-native-reanimated import to demonstrate that the flicker goes away.
https://user-images.githubusercontent.com/175330/199777019-c6c9c320-fa57-428d-934c-09f2468e7882.mp4
Snapshot of the buggy frame

Code to reproduce
// App.js
import * as React from "react";
import { View, Pressable, Text } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import Animated, { FadeIn } from "react-native-reanimated";
const Stack = createNativeStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Screen" component={Screen} />
</Stack.Navigator>
);
}
function Screen() {
const [isCopied, setCopied] = React.useState(false);
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Pressable onPress={() => setCopied((prev) => !prev)}>
{isCopied ? (
<View style={{ flexDirection: "row", alignItems: "center" }}>
<View style={{ width: 16, height: 16, backgroundColor: "red" }} />
<Text style={{ color: "red" }}>Copied</Text>
</View>
) : (
<View style={{ flexDirection: "row", alignItems: "center" }}>
<Text style={{ color: "red" }}>1238172938719873</Text>
<View style={{ width: 16, height: 16, backgroundColor: "red" }} />
</View>
)}
</Pressable>
</View>
);
}
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}
// babel.config.js
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["react-native-reanimated/plugin"],
};
};
Expected behavior
I wouldn't expect a flicker when react-native-reanimated is imported.
Reproduction
https://snack.expo.dev/@fungiblejen/stack-navigator-%7C-react-navigation
Platform
- Android
- iOS
- Web
- Windows
- MacOS
Packages
- @react-navigation/bottom-tabs
- @react-navigation/drawer
- @react-navigation/material-bottom-tabs
- @react-navigation/material-top-tabs
- @react-navigation/stack
- @react-navigation/native-stack
Environment
- I've removed the packages that I don't use
| package | version |
|---|---|
| @react-navigation/native | ^6.0.13 |
| @react-navigation/native-stack | ^6.9.1 |
| react-native-reanimated | 2.9.1 |
| react-native | 0.69.6 |
| expo | 46.0.16 |
| node | 18.7.0 |
| npm | 8.15.0 |
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the supplied reproduction locally in an Android emulator, since the Snack does not show the flicker reliably. Start with App.js and babel.config.js, comparing behavior with and without the react-native-reanimated import. Done means the conditional views no longer overlap or flicker on Android while the reproduction remains functional.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, javascript, react-native
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100