react-navigation / react-navigation/react-navigation

[Android] Conditional views flicker when `react-native-reanimated` is imported

Open
#10,977 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug library:react-native-reanimated platform:android platform:macos repro provided
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

CleanShot 2022-11-03 at 16 23 26

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.