Estoy usando Typescript y como esta pregunta es más teórica, solo publicaré el código necesario. Tengo una navegación de pestaña superior de material que se ve así:
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> ); };Pantalla de inicio.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(); ... } El objetivo es hacer que swipeEnabled sea igual a las variables isloading e isInitialized de HomeScreen. Así que debería verse así:
TabNavigator.tsx
screenOptions={{ lazy: true, tabBarStyle: {display: 'none'}, swipeEnabled: !isLoading || !isInitialized, // <-- how do I get this here? }} El problema es, ¿cómo obtengo las variables isLoading e isInitialized del componente HomeScreen al componente GameTabs ?
Cree otro estado dentro del componente GameTabs y pase su función setState a cada componente de la pantalla para realizar un seguimiento de las variables isLoading e isInitialized .
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> ); };Pantalla de inicio.txs
Dentro de HomeScreen , use useEffect para establecer el estado swipeEnabled con las variables isLoading e isInitialized dentro de la matriz de dependencias de 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]); ... }Esta es una solución que funciona, pero @Kavindu Vindika ofreció una solución que puede ser más limpia.
Encontré la solución. Resulta que el accesorio de navegación que se pasa a cada pantalla tiene un método setOptions . Así que simplemente puede llamar a eso cuando se monta cada pantalla. Por ejemplo, después de buscar el accesorio de navegación, simplemente hice lo siguiente:
navigation.setOptions({swipeEnabled: !isLoading});Esto resolvió mi problema.