React Native drawer navigator to stack navigator missing transition animation - react-native

I have a functional Drawer navigator that holds a Stack navigator as shown below:
function DrawerNavigator() {
return (
<Drawer.Navigator>
<Drawer.Screen
name="Categories"
component={CategoriesScreen}
... />
),
}}
/>
<Drawer.Screen
...
</Drawer.Navigator>
);
}
...
return (
<>
...
<NavigationContainer onReady={onLayoutRootView}>
...
<Stack.Screen
name="MealCategories"
component={DrawerNavigator}
options={{ headerShown: false }}
/>
While in the 'Favorites' screen, which is registered under the Drawer Navigator, when attempting to navigate to 'Categories' page which is registered under Stack navigator (but pointed to using Drawer navigator) using navigation.navigate(), there's no navigation animation.
const buttonPressHandler = () => {
navigation.navigate("Categories");
};

Yup it seems the drawer navigator has no support for screen animation. So it all looks great when using the drawer to navigate. But if navigating through links in the page or actions, theres no navigation animation between screens. Been hunting for hours now and I think its simply not implemented.

Related

React Native Navigation: Another Navigator is already registered for this container

I want my component to render a TopTab Navigator on the top and also a Drawer Navigator at the same time.
So something like
<TopTab.Navigator>
<TopTab.Screen />
</TopTab.Navigator>
<Drawer.Navigator>
<Drawer.Screen />
</Drawer.Navigator>
However I'm getting an error of "Another navigator is already registered for this container. You likely have multiple navigators under a single "NavigationContainer" or "Screen" Make sure each navigator is under a separate "ScreenContainer"
Why dont you try using it like this, drawerNavigator holds as the main wrapper and inside it topTab
const HomeScreen = () => {
return(
<TopTab.Navigator>
<TopTab.Screen />
</TopTab.Navigator>
)
}
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
</Drawer.Navigator>
</NavigationContainer>
)
}
This should work, feel free for doubts
You have to set Tab navigator inside drawer navigator, you can search to get better solutions like "how we use multiple navigator in react native?"
visit below link
https://dev.to/easybuoy/combining-stack-tab-drawer-navigations-in-react-native-with-react-navigation-5-da

react native navigate between screen

I have a project in react native in which I wanted to implement a feature.
I have three screens
slash screen
login screen
home screen
the slash screens last 1 second and leave on the home screen while the number of times the app has been opened does not exceed 3 times.
otherwise we display the login screen to ask for a password
About how to make the splash screen last 1 second, on Splash component, put an useEffect like this:
function Splash({ navigation }) {
useEffect(() => setTimeout(navigation.navigate('Home')),[]);
return (
<View>
<Image />
</View>
);
}
About conditional first screen when open the app, you can pass initialRouteName as a prop of Stack.Navigator:
import { createStackNavigator } from '#react-navigation/stack';
const Stack = createStackNavigator();
function App() {
return (
<Stack.Navigator initialRouteName={times < 3 ? Slash : Login}>
<Stack.Screen name="Slash" component={Slash} />
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Login" component={Login} />
</Stack.Navigator>
);
}
Note: my examples above use StackNavigator and on React Navigation v6, it works the same as TabNavigator and other versions of React Navigation.

React Navigation: How to trigger navigation.push() in bottom tab navigator?

Here is what I am trying to do in my app with react navigation:
There is a default bottom tab navigator.
The app will listen to changes in the data.
If there is a change in the data for any of the screens in the bottom tab navigator, trigger navigation.push() to refresh the component.
What I observed is that the default behavior of the bottom tab navigator is navigation.navigate()...i.e. unless I reload the app, the screens do not refresh themselves.
In short, how do I trigger navigation.push() in the tab navigator? e.g. in the sample code below, how do I set the navigation behavior?
Thanks a lot in advance!
//How do I trigger navigation.push() when each of the bottom tab is pressed?
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
Pulled the following example from my code which solved the issue for me;
import { StackActions } from '#react-navigation/routers';
onPress={() => {
const pushAction =
StackActions.push('ProfileAnimal', { animal_id: item.id });
this.props.navigation.dispatch(pushAction);
this.props.navigation.navigate('ProfileAnimal', {animal_id: item.id});
};

Navigate from a screen in one navigator to a screen in another navigator

I am using react-navigation v5.
In my app. I have two navigators, one stack navigator one drawer navigator:
const LoginStack = createStackNavigator();
const Drawer = createDrawerNavigator();
I show either one based on login status:
{state.loggedIn? (
<LoginStack.Navigator
...>
<LoginStack.Screen
name='login'
component={LoginScreen}
/>
<LoginStack.Screen
name='register'
component={RegisterScreen}
/>
</LoginStack.Navigator>
) : (
<>
<Drawer.Navigator
initialRouteName={Landing}
drawerContent={props => <MyDrawerContent {...props} />}
>
<Drawer.Screen name="landing" component={LandingScreen} />
...
</Drawer.Navigator>
</>
)}
As you can see above, if user is not logged in I show LoginStack navigator , otherwise I show Drawer navigator. And if you look closely in the Drawer.Navigator part, I have declared my own drawer content MyDrawerContent.
Inside MyDrawerContent, I have a logout button. I would like to navigate user to the LoginScreen of LoginStack. I tried :
<Button title="Logout" onPress={() => props.navigation.navigate('login')}/>
But I get error: The action 'NAVIGATE' with payload {"name":"Login"} was not handled by any navigator.. Is it because I am navigating to a screen of another navigator which MyDrawerContent doesn't belong to? How to resolve it?
Since you create two completely separate navigation trees, you cannot navigate between them because login screen is not registered, and thus not available, when you're in the Drawer.Navigator.
However, what you really want to do instead in your Logout button onPress, is change the loggedIn state to false. That will re-render the main app component and render the LoginStack instead. It's not very clear how you pass the state down the component tree so I can't provide a specific code example but hopefully you get the idea.

React Navigation Reset on Nested Navigator

I am using React-Navigation v 5.0.1, I have a Drawer navigator nested inside Stack navigator that looks like this:
MainStack.js
function MainStack() {
return(
<Stack.Navigator>
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="HomeDrawerStack" component={HomeDrawerStack} />
</Stack.Navigator>
)
}
HomeDrawerStack.js
function HomeDrawerStack() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
</Drawer.Navigator>
)
}
When I tap a logout button on Home screen, how do I navigate to Login screen and reset / clear all other screens? (so it triggers the componentWillUnmount on other screens)
This code will navigate to Login Screen after clearing the stack. so that back button or back swipe will not work to navigate to HomeDrawerStack
navigation.reset({
index: 0,
routes: [{ name: "Login" }],
});
if I share how I handled it, it is like, I am sharing my code snippet as png here, so what I have done is appended Navigator with redux, and I use to change my stack or replace my stack by dispatching event to store attached to Navigator.