I have the exact same problem as described here. When navigating between screens using Tabs or a drawer, each screen is reloaded, causing issues with my app.
I have tried to follow some of the recommendations given in the thread, but I can't apply it with my code. E.g.:
For me the solution was to nest the navigators as child of the screen component and not inserting the navigator into the component property.
Wrap it in the top level of the file and assign it to a variable, then use that variable inside your component.
My drawer is composed of 4 shortcuts to 4 screens (Home, History, Groups, Settings). The first three are also available from the Home screen in bottom-tabs.
Here is my code:
Navigation.js
import React from "react";
import { TouchableOpacity } from "react-native";
import { NavigationContainer} from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { Entypo } from "@expo/vector-icons";
import Settings from "../screens/Settings";
import Loading from "../screens/Loading";
import AddGroup from "../screens/AddGroup";
import GroupList from "../screens/GroupList";
import Home from "../screens/Home";
import Groups from "../screens/Groups";
import History from "../screens/History";
const HomeStack = createStackNavigator();
const HomeStackScreen = ({ route }) => (
<HomeStack.Navigator}>
<HomeStack.Screen
name={route.name}
component={Home}
/>
</HomeStack.Navigator>
);
const HistoryStack = createStackNavigator();
const HistoryStackScreen = ({ route }) => (
<HistoryStack.Navigator>
<HistoryStack.Screen
name={route.name}
component={History}
/>
</HistoryStack.Navigator>
);
const GroupsStack = createStackNavigator();
const GroupsStackScreen = ({ route }) => (
<GroupsStack.Navigator>
<GroupsStack.Screen
name={route.name}
component={Groups}
/>
</GroupsStack.Navigator>
);
const AppTabs = createBottomTabNavigator();
const bottomTabsScreen = ({ route }) => (
<AppTabs.Navigator>
<AppTabs.Screen
name="Home"
component={HomeStackScreen}
/>
<AppTabs.Screen
name="History"
component={HistoryStackScreen}
/>
<AppTabs.Screen
name="Groups"
component={GroupsStackScreen}
/>
</AppTabs.Navigator>
);
const AppDrawer = createDrawerNavigator();
const AppDrawerScreen = ({ navigation }) => (
<AppDrawer.Navigator>
<AppDrawer.Screen name="Home" component={bottomTabsScreen} />
<AppDrawer.Screen name="History" component={HistoryStackScreen} />
<AppDrawer.Screen name="Groups" component={GroupsStackScreen} />
<AppDrawer.Screen name="Settings" component={Settings} />
</AppDrawer.Navigator>
);
const RootStack = createStackNavigator();
const RootStackScreen = () => {
const [isLoading, setIsLoading] = React.useState(true);
React.useEffect(() => {
setTimeout(() => {
setIsLoading(!isLoading);
}, 500);
}, []);
return (
<RootStack.Navigator mode="modal">
{isLoading ? (
<RootStack.Screen name="Loading" component={Loading} />
) : (
<RootStack.Screen
name="AppDrawerScreen"
component={AppDrawerScreen}
/>
)}
<RootStack.Screen
name="AddGroup"
component={AddGroup}
options={modalOptionStyle}
/>
<RootStack.Screen
name="GroupList"
component={GroupList}
options={({ navigation }) => ({
headerTitle: "Select an existing group",
})}
/>
</RootStack.Navigator>
);
};
export default () => {
return (
<NavigationContainer>
<RootStackScreen />
</NavigationContainer>
);
};
index.js:
import React from "react";
import Navigation from "./config/Navigation";
import { ConversionContextProvider } from "./util/ConversionContext";
export default () => (
<ConversionContextProvider>
<Navigation />
</ConversionContextProvider>
);
Final working code after following x00 recommendations:
useEffect(() => {
if (isFocusedGroups) setLoading(true);
const unsubscribe = navigation.addListener("focus", () => {
loadFlatlist("groups")
.then()
.catch((error) => console.error(error))
.finally(() => {
setLoading(false);
});
});
return unsubscribe;
}, [navigation, isFocusedGroups]);
modalOptionStyleis not defined. Probably it don't matter but obscures your issue. Same goes fornavigationprop inAppDrawerScreenyou are not actually using. Etc. Plz remove noise and make a minimal reproducible example (big chance you'll solve your problem yourself in the process). Also you should show some screens' code and the way you navigate. Also inline functionoptions={({ navigation }) => ({ headerTitle: "Select an existing group" })}can cause some rerenders, but probably only forGroupList. Anyway, we need more code