I notice that when I go to the AwayScreen and change the value of stateB by calling setStateB, the HomeScreen re-renders, even though the HomeScreen uses only stateA and the AwayScreen uses only StateB.
This only happens after I have clicked on the HomeScreen for the first time (i.e. only after its first render)
Finally, I notice the AboutScreen child never re-renders when the parent tab navigator re-renders, which is good and suggests children don't re-render just because the parent re-rendered.
I would like the HomeScreen to NOT re-render just because the AwayScreen has called setStateB. Is this possible? If so, how?
I have the following code in App.tsx:
console.log("Starting app");
const Tabs = createBottomTabNavigator();
const MyTabs = () => {
console.log("Tabs are rendering");
const [stateA, setStateA] = useState<number>(0);
const [stateB, setStateB] = useState<number>(0);
return (
<Tabs.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, size }) => {
let iconName;
if (route.name === "Home") {
iconName = focused ? "home" : "home-outline";
} else if (route.name === "Away") {
iconName = focused ? "away" : "away-outline";
} else if (route.name === "Scan") {
iconName = focused
? "bluetooth"
: "bluetooth-outline";
} else if (route.name === "About") {
iconName = focused ? "flower" : "flower-outline";
}
return (
<Ionicons
name={iconName}
size={size}
/>
);
},
})}
initialRouteName="Scan">
<Tabs.Screen
name="Scan"
children={props => (
<ScanScreen
setStateA={setStateA}
{...props}
/>
)}
/>
<Tabs.Screen
name="Home"
children={props => (
<HomeScreen
stateA={stateA}
{...props}
/>
)}
/>
<Tabs.Screen
name="Away"
children={props => (
<AwayScreen
stateB={stateB}
setStateB={setStateB}
{...props}
/>
)}
/>
<Tabs.Screen
name="About"
component={AboutScreen}
/>
</Tabs.Navigator>
);
};
const App = () => {
console.log(" ");
console.log("Top of App - rendering");
return (
<NavigationContainer>
<View style={globalStyles.navigationContainer}>
<MyTabs />
</View>
</NavigationContainer>
);
};
Experiment 1: I start on ScanScreen, click on AwayScreen and there it changes the value of stateB by calling setStateB when I click on a slider
The LOG output looks like the following if I never click on HomeScreen:
LOG Starting app
LOG Running "test_app" with {"rootTag":71}
LOG Top of App - rendering
LOG Tabs are rendering
LOG ScanScreen rendering
LOG AwayScreen rendering
LOG Tabs are rendering
LOG ScanScreen rendering
LOG AwayScreen rendering
Experiment 2: I start on ScanScreen, click on HomeScreen (it just displays stateA) then click on AwayScreen and there I change the value of stateB. I see that HomeScreen re-renders after I click on the slider on the AwayScreen to setStateB:
LOG Starting app
LOG Running "test_app" with {"rootTag":71}
LOG Top of App - rendering
LOG Tabs are rendering
LOG ScanScreen rendering
LOG HomeScreen rendering
LOG AwayScreen rendering
LOG Tabs are rendering
LOG ScanScreen rendering
LOG HomeScreen rendering
LOG AwayScreen rendering