React-native-screens: flickering and blinking view on navigation.goBack()

Created on 9 Jun 2019  Â·  79Comments  Â·  Source: software-mansion/react-native-screens

Thanks for the awesome library which reduced react navigation's memory usage in my case.
but when navigation.goBack() called, the view flickers.

react native version: 0.57.8
react navigation version: 2.18.0
react native screens version: 1.0.0-alpha.22
platform: Android
mode: Production
Device: Samsung Galaxy S6
Android Version: 7.0
Android bug

Most helpful comment

This works for me:

<View
      style={{
        flex: 1,
        backgroundColor: 'black',
      }}>
      <NavigationContainer>
        <StackNavigator />
      </NavigationContainer>
    </View>

it's the return of app.js file, NavigationContainer imported from react navigation V5
instead of black use your own color.

All 79 comments

react native version: 0.59.9
react navigation version: 3.11.0
react native screens version: 1.0.0-alpha.22
platform: Android
also hava the problem

@fangasvsass with your dependencies this bug did not appear.
also, I changed the usage position of useScreens() from top of my navigator config to top off my App.js file.
the suspicious thing is that I'm not sure this package working on the new position or not!!

113

based on reducing memory usage I think it is working now!

@ammoradi did u find out the real reason of the flickering? i have 0.59.7, react navigation version 3.11.0 (even tried the newest one) and alpha.22 of screens but i'm facing that problem. the usescreens() position is at the beginning of the app.js so that should not be the problem

@kotomono can I see your App.js?
I think this issue highly depends on the position of usescreens().

NOTE: beware of using this lib. based on my Firebase Crashlytics report, this lib crashes sometimes. Although because of good memory handling of this lib, I'm using it up to now.

i simply put it on top of the page, even before any other imports

thanks,
Roberto

Il Mer 31 Lug 2019, 10:26 امــیر مــحـمــد notifications@github.com ha
scritto:

@kotomono https://github.com/kotomono can I see your App.js?
I think this issue highly depends on the position of usescreens()

NOTE: beware of using this lib. based on my Firebase Crashlytics report,
this lib crashes sometimes. Although because of good memory handling of
this lib, I'm using it up to now.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/kmagiera/react-native-screens/issues/111?email_source=notifications&email_token=AF2YMWHDGE76B5RHHR5GZ23QCFEDXA5CNFSM4HWI7MM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3GP2MA#issuecomment-516750640,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF2YMWD5PWLTKBL43XXETS3QCFEDXANCNFSM4HWI7MMQ
.

@kotomono I used this in my index.js file like this:

import { AppRegistry } from 'react-native';
import { useScreens } from 'react-native-screens';
import App from './App';
import { name as appName } from './app.json';

useScreens();

AppRegistry.registerComponent(appName, () => App);

yep did that too.. sadly no changes.. it may be related to something else
in the views?

// @flow
import { useScreens } from 'react-native-screens';

import { AppRegistry } from 'react-native';
import App from 'App/App';
import { name as appName } from './app.json';
useScreens();
AppRegistry.registerComponent(appName, () => App);

‪Il giorno mer 31 lug 2019 alle ore 10:39 ‫امــیر مــحـمــد‬‎ <
[email protected]> ha scritto:‬

@kotomono https://github.com/kotomono I used this in my index.js file
like this:

useScreens();

AppRegistry.registerComponent(appName, () => App);

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/kmagiera/react-native-screens/issues/111?email_source=notifications&email_token=AF2YMWAQWJLZCWNWOR7C233QCFFTXA5CNFSM4HWI7MM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3GQ45I#issuecomment-516755061,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF2YMWFHWSI22BESIGGF4OTQCFFTXANCNFSM4HWI7MMQ
.

@kotomono maybe it is related to StackNavigator.
I am using SwitchNavigator mostly.
and this is my dependencies:

"react-native": "0.59.9"
"react-native-screens": "^1.0.0-alpha.22"
"react-navigation": "^3.11.0"

i'll try another check, thank you for ur help :)

Il Mer 31 Lug 2019, 10:54 امــیر مــحـمــد notifications@github.com ha
scritto:

@kotomono https://github.com/kotomono maybe it is related to
StackNavigators.
I am using SwitchNavigator mostly.
and this is my dependencies:

"react-native": "0.59.9"
"react-native-screens": "^1.0.0-alpha.22"
"react-navigation": "^3.11.0"

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/kmagiera/react-native-screens/issues/111?email_source=notifications&email_token=AF2YMWHYLXZCW27QEPSCVIDQCFHLBA5CNFSM4HWI7MM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3GSEXY#issuecomment-516760159,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF2YMWF3TGYQRXOHILRMXYTQCFHLBANCNFSM4HWI7MMQ
.

Anything here? I use react navigation 5 (next) and react native-screens 2.0.0-alpha.11. On iOS all fine. On Android I see flickering. I've disabled animation between screens.

using

"react-native": "0.60.4",
"react-navigation": "^3.11.1",
"react-native-screens": "^1.0.0-alpha.23"

this bug disappeared!
there are switch, drawer and stack navigators in my test case

Looks like this issue is outdated. Can I close it @ammoradi ?

@WoLewicki I did ;)

I am also experiencing this issue. @ammoradi it looks like downgrading the version of react-native-screens fixed the issue for you?

@wcandillon No, I used the latest version of RN and react-native-screens when I used this lib.
https://github.com/software-mansion/react-native-screens/issues/111#issuecomment-558098262 on Nov 25, 2019

@ammoradi Don't look like that you used the last available versions.
They have to be the following, or am I wrong?!?:

"@react-navigation/native": "^5.1.5",
"@react-navigation/stack": "^5.2.10",
"react": "16.11.0",
"react-native": "0.62.2",
"react-native-screens": "2.6.0",

The issue still appears with like described above. Only thing that work is to remove react-native-screen from the App.
@ammoradi So please reopen this ticket

Ok seems it came back to newer versions.

Can someone provide a repo with minimal configuration needed to reproduce the issue?

It's actually crashing the app.

It seems this bug appears occasionally!
for me, this bug disappeared with this change but people saying it is also appearing for them :S

Yeah, but I would love to see a repo with minimal configuration to recreate it so I can work on it.

there is no solution yet, I face same issue on android. so I just disable enableScreens and error disappear but that's not correct

    "react-native": "0.62.2",
    "react-navigation": "^4.3.9",
    "react-native-screens": "^2.8.0",

Here is a repo @WoLewicki :

https://snack.expo.io/@derk-jan/header-flash

  • If enableScreens is commented out, everything works as expected.
  • If enableScreens is not commented out, on Android (REAL device) the header flashes white on _back_ navigation. At first I thought it was somehow react-native-paper, but it also happens with just a solid background color.

Between testing you'll need to _hard close_ the expo instance on the android device to make the cache clear or the problem won't show up/won't disappear when enabling/disabling enableScreens.

Hmm Expo does not contain the newest native code of react-native-screens. Could you wait till the release of Expo SDK38 and see if the problem exists there? And if so report it here? Another way of checking is to reproduce the issue in the bare RN project which would be easier for me to debug.

@WoLewicki I use RN CLI project and there is this same problem, with all up to date versions, I even updated my navigation to 5 version but same result(first I encountered this error on react navigation 4 version).

@beqramo so can you provide a repo with easy reproduction of the issue?

@WoLewicki that's correct. It's versions behind. @beqramo can you create the minimal repo for Wojciech? Otherwise I can do it if that's difficult for you.

@WoLewicki

okay I wrote some codes on fresh project and result is the same

here is a gif:

App

import React from 'react';
import {StatusBar} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';

import Screen1 from './Screen1';
import Screen2 from './Screen2';

const ApplicationStackNavigator = createStackNavigator();

const App = () => {
  StatusBar.setBackgroundColor('transparent', true);
  StatusBar.setTranslucent(true);
  return (
    <NavigationContainer>
      <ApplicationStackNavigator.Navigator
        initialRouteName={'Screen1'}
        screenOptions={{
          gestureEnabled: true,
          gestureDirection: 'horizontal',
          // animationEnabled: false,
        }}
        headerMode={'none'}
        mode={'card'}>
        <ApplicationStackNavigator.Screen name="Screen1" component={Screen1} />
        <ApplicationStackNavigator.Screen name="Screen2" component={Screen2} />
      </ApplicationStackNavigator.Navigator>
    </NavigationContainer>
  );
};

export default App;

Screen2 (sorry for inline styles, I was in hurry)

import React, {useEffect} from 'react';
import {View, Text} from 'react-native';

import {useNavigation} from '@react-navigation/native';
import {TouchableOpacity} from 'react-native-gesture-handler';

const Screen2 = () => {
  const navigation = useNavigation();

  return (
    <View
      style={{
        backgroundColor: '#08141B',
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      }}>
      <TouchableOpacity
        onPress={() => navigation.goBack()}
        style={{backgroundColor: 'blue'}}>
        <Text>go back</Text>
      </TouchableOpacity>
    </View>
  );
};

export default Screen2;

Screen1

import React, {useEffect} from 'react';
import {View, Text} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import {TouchableOpacity} from 'react-native-gesture-handler';

const Screen2 = () => {
  const navigation = useNavigation();

  return (
    <View
      style={{
        backgroundColor: 'black',
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      }}>
      <TouchableOpacity
        style={{backgroundColor: 'blue'}}
        onPress={() => navigation.navigate('Screen2')}>
        <Text>to screen 2</Text>
      </TouchableOpacity>
    </View>
  );
};

export default Screen2;

package.json

    "@react-native-community/masked-view": "^0.1.10",
    "@react-navigation/native": "^5.5.1",
    "@react-navigation/stack": "^5.5.1",
    "react": "16.11.0",
    "react-native": "0.62.2",
    "react-native-dialogs": "^1.1.0",
    "react-native-gesture-handler": "^1.6.1",
    "react-native-reanimated": "^1.9.0",
    "react-native-safe-area-context": "^3.0.6",
    "react-native-screens": "^2.9.0"

I reproduced it and it looks like the white flash appears due to the screen you are transitioning to not being attached already at the beginning of the transition. Currently, it is inevitable due to asynchronous calls of the bridge to the native side, which attaches the screen at the beginning of the transition. As a workaround, you can make the container have the same color as the screens, so there won't be a difference in colors while starting transition.

Okey, thanks for your attention, but currently I'm using react-navigation 4 in my project and is there any way to change the container color? I have already tried this but no result:

cardStyle: {
        backgroundColor: 'black',
        opacity: 1,
      },

and do you have any idea when this bug will be fixed?

thank you

for thus who face same issue I think above mentioned workaround to change background color is good enough, for my project I add android style.xml file this(it's not perfect but it's doing its job) :

android/app/src/main/res/values/styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- .... -->
        <item name="android:windowBackground">#11222D</item> <!-- added this, with your custom color-->
        <item name="android:statusBarColor">#11222D</item>  <!-- added this, with your custom color -->

    </style>

</resources>

I would not consider this as a bug, but rather the way the RN works. It could be changed when Fabric is launched with synchronous updates. We are thinking of e.g. keeping the 2 last screens attached in the native side, so the transitions like this one wouldn't cause the blinking, but it is rather a workaround, not a solution to a problem itself.

@WoLewicki
Okay, thanks again. have a nice work

Any fix? it looks terrible on dark theme

@sa8ab add a [dark] background color to your native screen / expo background color to workaround this.

@SleeplessByte Could you please share an example snippet of code?

For expo it's https://docs.expo.io/workflow/configuration/#backgroundcolor. You could have searched this yourself.

As posted by beqramo, for Android (bare) it's:

for thus who face same issue I think above mentioned workaround to change background color is good enough, for my project I add android style.xml file this(it's not perfect but it's doing its job) :

android/app/src/main/res/values/styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- .... -->
        <item name="android:windowBackground">#11222D</item> <!-- added this, with your custom color-->
        <item name="android:statusBarColor">#11222D</item>  <!-- added this, with your custom color -->

    </style>

</resources>

For iOS, change the storyboard.

@SleeplessByte The above workaround does not work for me on Android. The background and status bar colors are applied but the white flicker is still there.

Edit: changing my root navigator's cardStyle background property seemed to produce the "workaround". The issue is that the flicker is still there and can be seen over any elements that do not share the same background color.

The other option is to _not_ use react-native-screens for now.

I understand that and that is why I'm running it only on iOS only with different configurations on each platform.

In my opinion, the viability of it on Android is diminished with this bug. Are there any plans to look into this bug?

This works for me:

<View
      style={{
        flex: 1,
        backgroundColor: 'black',
      }}>
      <NavigationContainer>
        <StackNavigator />
      </NavigationContainer>
    </View>

it's the return of app.js file, NavigationContainer imported from react navigation V5
instead of black use your own color.

@sa8ab the flicker is still there. If you have any components on the next page that are not black, you will notice the flicker.

I spotted another issue about going back, the SVG from react-native-svg goes transparent when you go back the screen, on navigating to a screen it behaves correctly.

@iagormoraes can you provide a repo/snack with this bug in a new issue?

This works for me:

<View
      style={{
        flex: 1,
        backgroundColor: 'black',
      }}>
      <NavigationContainer>
        <StackNavigator />
      </NavigationContainer>
    </View>

it's the return of app.js file, NavigationContainer imported from react navigation V5
instead of black use your own color.

Thank you so much, worked for me

You can add screenOptions with cardStyle prop to your Stack.Navigatior for react-navigation 5+

    screenOptions={{
            cardStyle: {
              backgroundColor: 'your background color',
            },
          }}
        >

In my case i was using <Host> from react-native-portalize before all routing in App.js

example:

 <ThemeManager>
      <NotifierWrapper>
        <SafeAreaProvider>
          <PortalProvider>
            <Host style={{ width: width, height, backgroundColor: "#000" }}>.  <---- adding background color here fixed the white flash
              <Routes />
              <FlashMessage position="top" />
            </Host>
          </PortalProvider>
        </SafeAreaProvider>
        <FullScreenAlert />
        <SetCrashlyticsID />
      </NotifierWrapper>
    </ThemeManager>

After the introduction of #624, you can apply https://reactnavigation.org/docs/stack-navigator#detachpreviousscreen (from version 5.10.0) for the previous screen to stay attached after the transition. It should cause the goBack() action to not produce flickering. Can you check it and share your view on this?

@WoLewicki With react-native-screens@^2.14.0, enableScreens(true), and detachPreviousScreen: false I am no longer seeing a flicker when calling goBack()

@WoLewicki With react-native-screens@^2.14.0, enableScreens(true), and detachPreviousScreen: false I am no longer seeing a flicker when calling goBack()

where the detachPreviousScreen goes?

@ningacoding it goes to options of the screen. It makes the previous screen stay attached in the native view hierarchy after the transition. Please keep in mind that it is a recursive operation and applying it to all screens will remove the benefit of detaching the screens (performance boost). If you spot the flickering on every screen, the best option is to have the two top-most screens' detachPreviousScreen set to false, while the rest of them to true.

@WoLewicki this isn't implemented in native-stack yet, right?

native-stack uses native navigation components and there is no need to implement such things there. The attaching/detaching and animations of screens are provided by the platform there.

A good option to enforce the behavior of always having the previous and only previous screen mounted is to add mode="modal" to your stack-navigator. It applies such behavior without the need to specify it by yourself (normally in modal, you want to see the screen below in stack). Can you check if it works OK in all cases?

Nothing worked for me with React Navigation 4. This is what worked for me to resolve flickering.
animationEnabled: false

@sharadrb in React Navigation 4, the stack navigator must be at least of version 2.9.0 for the changes from react-native-screens 2.14.0 to be applied.

Here is a repo @WoLewicki :

https://snack.expo.io/@derk-jan/header-flash

  • If enableScreens is commented out, everything works as expected.
  • If enableScreens is not commented out, on Android (REAL device) the header flashes white on _back_ navigation. At first I thought it was somehow react-native-paper, but it also happens with just a solid background color.

Between testing you'll need to _hard close_ the expo instance on the android device to make the cache clear or the problem won't show up/won't disappear when enabling/disabling enableScreens.

Exactly, commented enablescreens and the flickering disappears (here is my config: RN 0.63.3)
What I did as a workaround (and it works fine), is to disable enablescreen only in the screens where i have the goBack action:

enableScreens(false);

Guys, enabling this function is recommended in the docs, so I don't think my solution is great?

@mostafero using enableScreens(false); resolves in react-native-screens not being used in the project, so the screens are not detached when navigating from them. It will result in no performance gain from the usage of the library, but also the bugs coming from it will disappear. You can try the solution provided here: https://github.com/software-mansion/react-native-screens/issues/111#issuecomment-728158231. It will make the performance gain stay, but should resolve this particular issue.

@mostafero using enableScreens(false); resolves in react-native-screens not being used in the project, so the screens are not detached when navigating from them. It will result in no performance gain from the usage of the library, but also the bugs coming from it will disappear. You can try the solution provided here: #111 (comment). It will make the performance gain stay, but should resolve this particular issue.

mode="modal" not working as well

@mostafero Can you provide a test example in TestsExample project (https://github.com/software-mansion/react-native-screens/tree/master/TestsExample) with minimal configuration needed to reproduce the issue?

Finally fixed it keeping enableScreen, I realized that i was setting headerMode="float" to my root stack navigator, removing headerMode fixed the issue of flickering

const AppStack = createStackNavigator();

```typescript
initialRouteName="HOME"
// headerMode="float" ---- removed headerMode
>
name="HOME"
component={HomeStack}
/>
.....

fyi, i am using `gestureEnabled: true,` as  `screenoptions` for my stack navigator.

Package.json
```json
    "react": "16.13.1",
    "react-native": "0.63.3",
    "react-native-screens": "^2.15.0",

I spotted another issue about going back, the SVG from react-native-svg goes transparent when you go back the screen, on navigating to a screen it behaves correctly.

In our project we are having the exact same issue, it is reproducible in every screen that has an SVG.
This happens on screens inside react-native-screens/native-stack navigator.
Both react-navigation and react-native-screens are on their latest versions.

@WoLewicki any suggestions?

This works for me. With enableScreens() also. Resolved the flicker/white edge in dark theme when switch screen.

<Stack.Navigator
  screenOptions={({ navigation }) => {
    return {
      detachPreviousScreen: !navigation.isFocused(),
    }
  }}
>

I spotted another issue about going back, the SVG from react-native-svg goes transparent when you go back the screen, on navigating to a screen it behaves correctly.

facing the same issue, repro snack: https://snack.expo.io/@hehex/native-stack-svg-blink.

only happens in native-stack (createNativeStackNavigator), @react-navigation/stack works fine.


video

https://user-images.githubusercontent.com/9209882/104156012-426d9b00-5423-11eb-9e11-cf1de5d0aa66.mp4

@hehex9 can you open another issue about the SVG with all the information required? It will be easier if we keep the discussion of the certain problems in one place.

Hey guys!

Came here for a solution and ended up updating react-native-screens to the latest version:
"react-native-screens": "^2.17.1"(at the time of this comment) and the flickering is gone.

Here are my other specs for those who wanna reproduce:
`````
"react": "16.13.1",
"react-native": "0.63.2",

"@react-navigation/native": "^5.7.3",
"@react-navigation/stack": "^5.9.0",
"react-native-screens": "^2.17.1",
```````

EDIT: "@react-navigation/stack": "^5.9.0" is important

Happy coding!

I think we can close this issue since the original problem is solved by the provided solutions. Feel free to comment here if you have any questions or if something is wrong.

Seems like the flickering is still occuring if using @react-navigation/stack version 5.10.0 or above.
However, if we set to 5.9.x, flickering will stop but we would get a warning asking for updating to a version above equal or above 5.10.0. Please provide a fix to make it work with @react-navigation/stack version 5.10.0 or above as well.

@markoj3s did you apply suggestions from this thread to your navigation, e.g. https://github.com/software-mansion/react-native-screens/issues/111#issuecomment-757518915 ?

@WoLewicki Sorry for the late reply, just noticed now your reply.
I have looked at the suggestions, but could only find some workarounds and no real fixes.
(#111 is one of those workarounds)

if (active !== undefined && activityState === undefined) { console.warn( 'It appears that you are using old version of react-navigation library. Please update @react-navigation/bottom-tabs, @react-navigation/stack and @react-navigation/drawer to version 5.10.0 or above to take full advantage of new functionality added to react-native-screens' ); activityState = active !== 0 ? 2 : 0; // in the new version, we need one of the screens to have value of 2 after the transition }
According to the code and comment, when using react navigation stack < 5.9, the only difference is that activityState is given a value.
So I guess somewhere is buggy when using stack >= 5.10, activityState might not get any value at some point?

I am not sure what you mean in your last sentence. We changed the integration between react-native-screens and react-navigation's stack navigator to better address the cases of modals and the blinking caused by detaching the screen below before the transition is over. It was published in version 5.10.0 of stack and 2.14.0 of react-native-screens, so to take advantage of those changes, you need to have at least those versions. activityState is the new prop that takes care of properly managing attaching/detaching the screens and should always be provided by react-navigation.

This works for me:

<View
      style={{
        flex: 1,
        backgroundColor: 'black',
      }}>
      <NavigationContainer>
        <StackNavigator />
      </NavigationContainer>
    </View>

it's the return of app.js file, NavigationContainer imported from react navigation V5
instead of black use your own color.

it worked for me in stack navigation and native stack
tnx.

Hi Guys ,

  1. install react-native-screens as - > npm install --save react-native-screens
  2. import it in App.js and make enableScreens property as true as such

import { enableScreens } from 'react-native-screens';
enableScreens(true);

it worked for me .

@WoLewicki With react-native-screens@^2.14.0, enableScreens(true), and detachPreviousScreen: false I am no longer seeing a flicker when calling goBack()

thnx

I just hit in this issue again, on 3.0.0 (via Expo), screen will flickering sometime when go back in ios (with the content from last screen). Any idea ?

I had a same issue with 3.0.0 (also via Expo).
I tried with 3.1.1 and 2.18.1, 2.18.1 seems like it doesn't have any flickering so I'lll stick to it untill it is solved.
It gives me a warning but it seems like it is working without any problem so far.

@hunterbmt any luck with the flickering on iOS? We are experiencing the exact same issue. I've already tried with detachPreviousScreen which should be default for iOS anyway, from the docs, and of course enableScreens(true); but the issue persists. Also tried downgrading to 2.18.1 but no luck there. I'm on react-navigation 4.x

Flickering goes away when disabling react-native-screens

The issue with iOS has already been reported here https://github.com/software-mansion/react-native-screens/issues/905 which seems to be slightly different from this one.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pvinis picture pvinis  Â·  5Comments

thomasgosse picture thomasgosse  Â·  4Comments

iDuuck picture iDuuck  Â·  5Comments

OmarBasem picture OmarBasem  Â·  4Comments

ArekChr picture ArekChr  Â·  5Comments