Create Bottom Tab Navigator Using CMS Content - react-native

I have a React Native application where the tabs in the bottom tab navigator will be authored through Drupal. As a result I need to not hard-code the various tabs in the navigator. I tried the following:
screenOptions={{
tabBarStyle: { display: isAuthenticated ? undefined : 'none' },
}}
>
{mockData.map({ item => {
<Tab.Screen
name={item.name}
component={item.route}
/>
}})}
</Tab.Navigator>
but I keep getting an error that there are no screens for the navigator, so it seems putting it inside a map is making it invisible. I'm getting frustrated with how to get this content into the navigator.

Related

How can I redirect from StackNavigator screen to BottomTabNavigator screen

I'm working on an app in React-Native. How I'm trying to achieve this is by using a SignUpCompleted Flag and checking if its true/false to decide if the page should navigate to the next signup screen or just to the homepage. I have 3 screens as part of the sign-up process that I only want to be shown the 1st time the app opens. I have the 3 screens in a StackNavigator and I'm trying to navigate from the last StackNavigator screen to a BottomTabNavigator screen. Sadly I get the following error:
The action 'NAVIGATE' with payload {"name":"HomeStack"} was not handled by any navigator.
My current setup is as follows:
SignUpStack
const SignUpStack = createStackNavigator();
export default function SignUpStackScreen() {
const [signUpCompleted, setSignUpCompleted] = useState(false);
return (
<SignUpStack.Navigator initialRouteName="Welcome" screenOptions={{ headerShown: false }}>
<SignUpStack.Screen name="Welcome" component={WelcomeScreen} initialParams={{signUpCompleted}} />
<SignUpStack.Screen name="Department" component={ChooseDepartment} initialParams={{signUpCompleted}} />
<SignUpStack.Screen name="InputName" component={InputName} initialParams={{signUpCompleted, setSignUpCompleted}}/>
</SignUpStack.Navigator>
);
}
From the InputName component I try to redirect to a BottomTabNavigator Screen called homename
The redirect code is as follows: - in InputName component
<TouchableOpacity
style={[styles.shadow]}
onPress={() => {navigation.navigate("HomeName"); setSignUpCompleted(true)}}
>
The BottomTabNavigator is as follows: - I'm trying to redirect to HomeStack component
-const Tab = createBottomTabNavigator();
export default function Tabs() {
return (
<Tab.Navigator initialRouteName={homeName} >
<Tab.Screen name={ResultsName} component={ResultatenStack} />
<Tab.Screen name={homeName} component={HomeStack} />
<Tab.Screen name={settingsName} component={SignUpStack} />
</Tab.Navigator>
);
}
When using the same navigation method to direct to screens that are in the stack that I already am, it works fine. I hope someone can give me any pointers or help out! If you need any more info feel free to reach out!
PS: I'm very new to react-native so my apologies if I'm missing information.
I geas you are trying to navigate from stack navigator to tab navigator which is not ideal in react native you have to use nesting navigator
what I mean you have to use the tab navigator as a screen inside the stack navigator
this is React Navigation doc for nesting navigator https://reactnavigation.org/docs/nesting-navigators/

Menu Button To Left Of Stack Navigator Back Button, headerBackVisible: true not working

I'm using a stack navigator nested in a drawer navigator for a react native app using react navigation 6. I'm only showing the header for the stack navigator. I want to put a hamburger menu button on the far left of the header, BUT I also want the default stack navigation back button to be present.
I found the setting headerBackVisible in the documentation, but haven't been able to find any examples of anyone using it, so I'm not sure if I'm using it properly. I'm trying to pass it as headerBackVisible: true in my screen options. No matter what I do, if I put anything else in headerLeft, I cannot get the header back button to show.
Anyone have any suggestions or examples on how to put something to the left of the header back button?
Yes, headerBackVisible is not working with headerLeft. As a workaround, you can import default back button (HeaderBackButton) from #react-navigation/stack and return it along with your hamburger component. Something like this:
import { createStackNavigator, HeaderBackButton } from '#react-navigation/stack';
<Stack.Navigator
screenOptions={({ navigation, route }) => ({
headerLeft: (props) => {
return (
<>
<Text>Menu</Text> // Replace with your hamburger component
{props.canGoBack && <HeaderBackButton {...props} />} // THIS IS WHAT YOU NEED
</>
);
},
})}> ....
<Stack.Screen ... />
<Stack.Screen ... />
</Stack.Navigator>
Snack link: https://snack.expo.dev/#rabiarashid/react-navigation---stack-navigator-example
Update (for react-navigation v6):
In v6, HeaderBackButton is moved to elements library i.e.
import { HeaderBackButton } from '#react-navigation/elements';
Ref: https://reactnavigation.org/docs/upgrading-from-5.x/#some-exports-are-now-moved-to-the-element-library

How do I add a navigation button to a React Navigation Stack header with nested Bottom Tab Navigator?

I am trying to build a mobile app in react-native and I'm having some problems setting up React Navigation.
What I want to achieve is a Bottom Tab Navigator that Navigates to the 'Home' screen and the 'Profile' Screen. From the 'Home' screen, there should be a button to navigate to the 'Settings' screen in the Header.
I have got to the point where I have a Bottom Tab Navigator that can successfully navigate between the 'Home' and 'Profile' screens, as well as a button on the header for the Settings screen using the Stack navigation header. However, I am having trouble navigating to the 'Settings' screen with this button.
My code for the Stack navigator is:
const MainStackNavigator = () => {
return (
<Stack.Navigator screenOptions={screenOptionStyle}>
<Stack.Screen
name="Home"
component={HomeScreen}
options = { ({navigation}) => ({
title: "Home",
headerStyle: {
backgroundColor: '#ff6600',
},
headerRight: () => (
<Button
onPress={() => navigation.navigate(SettingScreen)}
title="Settings"
color="#fff"
/>
)
})}
/>
<Stack.Screen name="Settings" component={SettingScreen} />
</Stack.Navigator>
);
}
When I click on the Settings button, I get the error:
"The action 'NAVIGATE' with payload undefined was not handled by any navigator.
Do you have a screen named 'SettingScreen'?"
Upon looking for a solution to this error I found this article: Nesting Navigators
It recommends keeping nested navigators to a minimal. Is my method even the right way about going for this UI design? Is there a way to achieve this with only using one navigator?
After some time trying to solve this I found the problem was quite silly of me. navigation.navigate takes the name of the screen to navigate to, but I was giving it the component.
To fix the problem I changed
onPress={() => navigation.navigate(SettingScreen)}
to
onPress={() => navigation.navigate('Settings')}
Add this below your render method!
render () {
const { navigate } = this.props.navigation;
}
And then in the onPress
onPress={() => navigate(SettingScreen)}
Hopefully this helps

Unable to Navigate to a StackNavigator nested in a DrawerNavigator

I started with a drawer navigation to allow me to pick a category page as a starting point. From each category page I want to create a stack navigator so that it navigates with a stack without each page displayed in the drawer. I started by adding a StackNavigator to the "product" page, but was told to move it to the app page and used a nest navigator. So far, this is what I have...
App.js ( Nested Navigators )
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="LoL"
drawerStyle={{
backgroundColor: "#212121",
}}
drawerContentOptions={{
activeTintColor: "orange",
inactiveTintColor: "white",
}}
>
<Drawer.Screen name="LoL" component={LoL} />
<Drawer.Screen name="CSGO" component={CSGO} />
<Drawer.Screen name="matchDetailsnav" component={matchDetailsNav} />
</Drawer.Navigator>
</NavigationContainer>
);
}
const matchDetailsNav = () => {
<Stack.Navigator>
<Stack.Screen name="MatchDetails" component={MatchDetails} />
</Stack.Navigator>
}
If we navigate to LoL.js we will see a list of cards to click on. I am using the following code to generate routes for each card.
{matches.map((match, index) => {
return (
<View>
<TouchableOpacity
key={index}
onPress={() => navigation.navigate('matchDetailsNav', match)}
>
<Card
.. passing some props here..></Card>
</TouchableOpacity>
</View>
This is where I started to get the following error...
The action 'NAVIGATE' with payload {** .. obj of the props im passing .. not important to question *} was not handled by any navigator.
Do you have a screen named 'MatchDetails?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.
This was happening before I added the stack navigator but I am not sure why. I am importing the MatchDetails page into the App.js, there is not naming typo in my code, and I cannot seem to find why it doesn't see my match details page. Why is it not picking up my page?
EDIT: I just noticed that adding the nested navigator like I did in the example above put the name "matchDetailsNav" in my drawer nav as a clickable link, which is not what I want.
I simply want to gave a drawer nav and then have regular stack navigation for the pages/screens that link within the drawer nav. This way, clicking on a card living on a screen that is accesable from the Drawer Nav should use a stack nav ( allowing for the back button and sliding animation ).
I hope this edit clears up exactly what I am trying to do.

How can I force TabBar to show in all App screens react-navigation v5?

I'm trying to show the Bottom TabBar in every screen in my app, but i can't find a way to do it in RN V5 yet,
So When i tried to use tabBarVisible like this
<BottomTab.Navigator
lazy={false}
tabBar={props => <TabBar {...props} />}
screenOptions={({route}) => (
console.log('route', route), it's just log the five bottom component i have
{
tabBarVisible: ({routes}) => {
let tabBarVisible = false;
console.log('screens', routes); // Not log anything!
return {tabBarVisible};
},
}
)}
....
>
... 5 Tabs here
</BottomTab.Navigator>
So How can i handle this case? and access to other stack screens?
just to minimize the code snippet in question
here's the full Root file code, can you check it?
If you want the tabBar to be shown in every screen of the app, you need to make it your root navigator and then all screens will be under that navigator, so the tabBar will be visible in all screens.