0

I'm experiencing this issue with my Expo React Native app on iOS only where a blank screen is displayed after swapping the Login screen with the Main screen based on simple component state change, e.g. Conditional rendering. This started to happen after upgrading from Expo 49 to 51.

video

Here's a minimal reproducible code.

import { Text, Button, View } from 'react-native';
import { useState } from 'react';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import { NavigationContainer } from '@react-navigation/native';

const MaterialTopTab = createMaterialTopTabNavigator();

export default function App() {
  const [authenticated, setAuthenticated] = useState(false);
  return (
    <NavigationContainer>
      <MaterialTopTab.Navigator tabBarPosition="bottom" screenOptions={{ tabBarStyle: { paddingBottom: 20 } }}>
        {!authenticated ? (
          <>
            <MaterialTopTab.Screen name="Login Screen 1">
              {(props) => <LoginScreen {...props} setAuthenticated={setAuthenticated} />}
            </MaterialTopTab.Screen>
            <MaterialTopTab.Screen name="Login Screen 2">
              {(props) => <LoginScreen {...props} setAuthenticated={setAuthenticated} />}
            </MaterialTopTab.Screen>
          </>
        ) : (
          <>
            <MaterialTopTab.Screen name="Main Screen 1">
              {(props) => <MainScreen {...props} setAuthenticated={setAuthenticated} />}
            </MaterialTopTab.Screen>
            <MaterialTopTab.Screen name="Main Screen 2">
              {(props) => <MainScreen {...props} setAuthenticated={setAuthenticated} />}
            </MaterialTopTab.Screen>
          </>
        )}
      </MaterialTopTab.Navigator>
    </NavigationContainer>
  );
}

const LoginScreen = ({ setAuthenticated }) => {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Login Screen</Text>
      <Button title="Log in" onPress={() => setAuthenticated((prev) => !prev)} />
    </View>
  );
};

const MainScreen = ({ setAuthenticated }) => {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Main Screen!</Text>
      <Button title="Log out" onPress={() => setAuthenticated((prev) => !prev)} />
    </View>
  );
};

Here's a minimal reproduction Expo Snack and a minimal reproduction project on GitHub

As you can see in the video, the initial Login screen is displayed, when I click on Log in, the state authenticated of this component changes to true and the Main screen should be rendered, but is not. The first Main screen only renders after I navigate to the second Main screen (or any other screen). The same thing happens when I click Log out, the first Login screen is not displayed until I navigate to the second Login screen.

This problem is only on iOS where Material Top Tab Navigator is used. I have tried other navigators like Stack, BottomTab, Drawer which work fine.

Has anyone had this problem and how to fix it?

Thank you

I have tried the following but nothing worked:

0