I'm using Typescript and since this question is more theoretical, I will only post the necessary code. I have a material top tab navigation looking like this:
TabNavigator.tsx
const Tab = createMaterialTopTabNavigator<GameTabParamList>();
const GameTabs: FC = () => {
return (
<Tab.Navigator
initialRouteName={Screens.HOME_SCREEN}
tabBarPosition="bottom"
screenOptions={{
lazy: true,
tabBarStyle: {display: 'none'},
swipeEnabled: false, // This should be equal to props that are found in the multiple screens
}}
backBehavior='none'>
<Tab.Screen
name={Screens.AVAILABLE_PRIZES_SCREEN}
component={AvailablePrizesScreen}
/>
<Tab.Screen name={Screens.HOME_SCREEN} component={HomeScreen} />
<Tab.Screen
name={Screens.WON_PRIZES_SCREEN}
component={WonPrizesScreen}
/>
</Tab.Navigator>
);
};
HomeScreen.txs
const HomeScreen: FC = () => {
const {
isInitialized,
isLoading,
adShowing,
playGame,
localCount,
isAnimationPlaying,
winAnimationRef,
handleWinAnimationFinished,
isFlashAnimationPlaying,
navToSettingsScreen,
displayPrizeId,
displayPrizeTitle,
displayPrizeDesc,
displayPrizeTier,
displayPrizeType,
isShowingPrize,
handleHidePrize,
handleFlashAnimationFinished,
navigation,
} = useHomeScreen();
...
}
The goal is to make the swipeEnabled equal to the HomeScreen's isloading
and isInitialized
variables. So it should look like this:
TabNavigator.tsx
screenOptions={{
lazy: true,
tabBarStyle: {display: 'none'},
swipeEnabled: !isLoading || !isInitialized, // <-- how do I get this here?
}}
The problem is, how do I get the isLoading and isInitialized variables from the HomeScreen
component to the GameTabs
component?
CodePudding user response:
Create another state inside GameTabs
component and pass it's setState
function to each screen component to keep track of isLoading
and isInitialized
variables.
TabNavigator.tsx
const Tab = createMaterialTopTabNavigator<GameTabParamList>();
const GameTabs: FC = () => {
const [swipeEnabled, setSwipeEnabled] = useState(false);
return (
<Tab.Navigator
initialRouteName={Screens.HOME_SCREEN}
tabBarPosition="bottom"
screenOptions={{
lazy: true,
tabBarStyle: {display: 'none'},
swipeEnabled: swipeEnabled,
}}
backBehavior='none'>
<Tab.Screen
name={Screens.AVAILABLE_PRIZES_SCREEN}
component={AvailablePrizesScreen}
/>
<Tab.Screen name={Screens.HOME_SCREEN} render={() => <HomeScreen setSwipeEnabled={setSwipeEnabled}/>} />
<Tab.Screen
name={Screens.WON_PRIZES_SCREEN}
component={WonPrizesScreen}
/>
</Tab.Navigator>
);
};
HomeScreen.txs
Inside HomeScreen
, use useEffect
to set swipeEnabled
state having isLoading
and isInitialized
variables inside the dependency array of the useEffect
.
const HomeScreen: FC = ({ setSwipeEnabled }) => {
const {
isInitialized,
isLoading,
adShowing,
playGame,
localCount,
isAnimationPlaying,
winAnimationRef,
handleWinAnimationFinished,
isFlashAnimationPlaying,
navToSettingsScreen,
displayPrizeId,
displayPrizeTitle,
displayPrizeDesc,
displayPrizeTier,
displayPrizeType,
isShowingPrize,
handleHidePrize,
handleFlashAnimationFinished,
navigation,
} = useHomeScreen();
useEffect(() => {
setSwipeEnabled(!isLoading || !isInitialized);
}, [isLoading, isInitialized]);
...
}
CodePudding user response:
EDIT
This is one solution that works, but @Kavindu Vindika offered a solution that may be cleaner.
Initial Answer
I found the soloution. Turns out, the navigation prop that get's passed to each screen has a setOptions
method. So you can simply call that when each screen gets mounted. For example, after I fetch the navigation prop I simply did:
navigation.setOptions({swipeEnabled: !isLoading});
This solved my problem.