how to handle react-navigation custom header back Button - react-native

i'm using react-navigation:
"#react-navigation/native": "5.2.3",
"#react-navigation/stack": "5.2.18",
and i have a custom header a specific screen but i need to handle back button to go back to previous screen but i don't have access to navigation prop to do that
function MainStackScreen() {
return (
<Stack.Navigator initialRouteName={'Splash'}>
<Stack.Screen name="Splash" component={Splash} options={{headerShown: false}}/>
<Stack.Screen options={{ style:{ borderTopWidth: 0, elevation: 0, shadowOpacity: 0 },
headerStyle:{height: hp('7%') }, header:()=><CustomHeader
title={i18n.t('myAds:header')} back bgColor={colors.white}
onPressHeader={()=>navigation.pop()} /> }} name="MyAdsTabs" component={MyAdsTabs} />
</Stack.Navigator>
);
}
<Provider store={store}>
<PersistGate persistor={persistor} loading={this.renderLoading()}>
<Root>
<NavigationContainer>
<MainStackScreen />
</NavigationContainer>
</Root>
</PersistGate>
</Provider>
it gives me an error with: ReferenceError: navigation is not defined
how can i have accessto navigation or something to handle back button

i passed navigation like this as the docs said react-navigation docs
<Stack.Screen options={({navigation})=>({ style:{ borderTopWidth: 0, elevation: 0, shadowOpacity: 0 },
headerStyle:{height: hp('7%') }, header:({goBack})=>
<CustomHeader title={i18n.t('myAds:header')} back bgColor={colors.white} onPressHeader={()=>navigation.pop()} /> })}
name="MyAdsTabs" component={MyAdsTabs} />

You have to define navigation in header as below :
function MainStackScreen() {
return (
<Stack.Navigator initialRouteName={'Splash'}>
<Stack.Screen name="Splash" component={Splash} options={{ headerShown: false }} />
<Stack.Screen
options={{
style: { borderTopWidth: 0, elevation: 0, shadowOpacity: 0 },
headerStyle: { height: hp('7%') },
header: ({ navigation }) => ( // defing navigation here
<CustomHeader
title={i18n.t('myAds:header')} back bgColor={colors.white}
onPressHeader={() => navigation.pop()}
/>
)
}}
name="MyAdsTabs"
component={MyAdsTabs}
/>
</Stack.Navigator>
);
}

Related

How to remove white space above a material top tab bar in react native

I'm looking for a way to remove the white space circled in red in my react native top tab bar.
The top tab bar is in a stack navigator which is a bottom tab navigator
const BottomTab = () => {
return (
<Tab.Navigator
style: { height: 55, borderTopWidth: 0, elevation: 0 },
}}
>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Recent" component={RecentStack} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
);
};
const RecentStack = () => {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="RecentTabs" component={RecentTopTabBar} />
<Stack.Screen name="TaskDetails" component={TaskDetails} />
</Stack.Navigator>
);
};
const RecentTopTabBar = () => {
return (
<Tab.Navigator >
<Tab.Screen name="Ongoing" component={OngoingJobs} />
<Tab.Screen name="Completed" component={CompletedJobs} />
</Tab.Navigator>
);
};
I have tried to put marginTop as a negative number but that just makes the tab disappear into the white space. The headerShown attribute is false so what could the white space be.
I know this is old and you've probably found a solution, but have you tried adding screenOptions={{ headerShown: false }} to your 'BottomTab' navigator?
I ran into a similar issue with react-navigation Bottom Tabs Navigator, and that resolved it.
If this is a (createMaterialTopTabNavigator)
then you should use "screenOptions" Prop:
screenOptions={{
tabBarStyle: {
paddingTop: 0,
marginTop: 0
},
}}
Note: Use The Prop should be Inside The <StackName.Navigator />
Example:
<TopTabs.Navigator
initialRouteName='...'
screenOptions={{
tabBarStyle: {
paddingTop: 0,
marginTop: 0
},
}}
>
....Screen's
</TopTabs.Navigator>

react navigation own header component

I created a own header file to use this as the header in stack screen.
It shows me the file but it shows the static datas too. Its overide and now I have 2 title and 2 buttons. What do I am wrong?
import HeaderAuth from '../shared/headerAuth';
...
...
export function Home() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={TabBar} />
<Stack.Screen name="addProduct" component={EmptyScreen} />
<Stack.Screen name="AuthRegister" component={AuthRegister}
options={
({ navigation }) => ({
headerStyle: {
elevation: 0,
shadowOpacity: 0,
flexDirection: 'row',
justifyContent: 'space-between'
},
headerLeft: () => <HeaderAuth />,
})} />
</Stack.Navigator>
</NavigationContainer>
);
}
I am very thankful for your help!!

React Native navigation error only when user is logged in

I have an option to browse a welcome screen not logged in, or logged in (and it shows more features). I thought I had the navigation configured correctly but I guess not. The error "The action NAVIGATE with payload... was not handled by any navigator" is leading me to believe it's because i'm using one navigator nested within another, BUT the weird thing is I do NOT get this error at all if the user is not logged in. It only happens when they are. The main button calls this signOut() function to either log them out and return to the main screen, or just return to the main screen if they aren't logged in. Did I not do this correctly? Or is it still likely to be my nested navigation problem in which case, why would it only give the error if the user is logged in?
function signOut(){
if (user){
auth
.signOut()
.then(() => navigation.navigate('StartScreen'));
} else {
navigation.navigate('StartScreen');
}
}
here is my AuthNavigator:
const Stack = createStackNavigator();
export default function AuthNavigator(){
// Set an initializing state whilst Firebase connects
const [initializing, setInitializing] = useState(true);
const [user, setUser] = useState();
// Handle user state changes
function onAuthStateChanged(user) {
setUser(user);
if (initializing) setInitializing(false);
}
useEffect(() => {
const subscriber = auth.onAuthStateChanged(onAuthStateChanged);
return subscriber; // unsubscribe on unmount
}, []);
if (initializing) return null;
if (user) {
return (
<MainHeader />
);
}
return (
<Stack.Navigator>
<Stack.Screen name="StartScreen" component={StartScreen} options={{ headerShown: false }} />
<Stack.Screen name="SignIn" component={SignIn} options={{ headerShown: false }} />
<Stack.Screen name="SignUp" component={SignUp} options={{ headerShown: false }} />
<Stack.Screen name="MainHeader" component={MainHeader} options={{ headerShown: false }} />
<Stack.Screen name="ForgotPassword" component={ForgotPassword} options={{ headerShown: false }} />
</Stack.Navigator>
)
}
And here is my nested Tab Navigator within the MainHeader screen. The WelcomeScreen has the logout button that performs the signOut() function I first listed:
export default function MainHeader() {
var user = auth.currentUser;
return (
<>
<View style={styles.headerContainer}>
<Image
style={styles.image}
source={require("../assets/newheader4.png")}
/>
</View>
<Tab.Navigator
tabBarOptions={{
activeTintColor: "blue",
inactiveTintColor: "black",
style: {},
tabStyle: {
width: "auto",
backgroundColor: "#e0d5f3",
borderTopWidth: 3,
borderBottomWidth: 3,
borderRightColor: "gray",
},
labelStyle: {
fontSize: 14,
fontWeight: "bold",
},
scrollEnabled: true,
}}
>
<Tab.Screen name="Home" component={WelcomeScreen} />
<Tab.Screen name="All Deals" component={MessagesScreen} />
<Tab.Screen name="My Favs" component={FavoritesScreen} />
<Tab.Screen name="Notifications" component={Notifications} />
<Tab.Screen name="Free Samples" component={FreeScreen} />
<Tab.Screen name="Who We Are" component={WhoWeAreScreen} />
</Tab.Navigator>
</>
);
}
Solution: remove the navigation line completely from the then() after auth.signOut. It does it by default and redirects to the StartScreen perfectly without it.
New signOut function:
function signOut(){
if (user){
auth
.signOut()
.then();
} else {
navigation.navigate('StartScreen');
}
}

undefined is not an object (evaluating 'object.keys(routeConfigs)') [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
This is the error I am receiving. Please tell me what file you need to see. Apologies if the problem is not to the point, I am a noob here.
First image shows the error
Below is the file which calls for stack navigator.
This file calls for stacknavigator
If you need anything else, please tell me, I'll add it in further edits
import React from "react";
import { Easing, Animated, Dimensions } from "react-native";
//import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import { createDrawerNavigator,DrawerItems} from 'react-navigation-drawer';
//import { createBottomTabNavigator } from 'react-navigation-bottom-tabs';
import { Block } from "galio-framework";
// screens
import HomeActivity from '../components/HomeActivity.js';
import ProfileActivity from '../components/ProfileActivity.js';
import Results from '../components/Results.js';
// import HomeActivity from "../screens/Home";
// import Onboarding from "../screens/Onboarding";
import Pro from "../components/Pro";
import Profile from "../components/Profile";
// import Register from "../screens/Register";
// import Elements from "../screens/Elements";
// import Articles from "../screens/Articles";
// drawer
import CustomDrawerContent from "./Menu";
// header for screens
import Icon from "../components/Icon";
import Header from "../components/Header";
import { argonTheme, tabs } from "../constants";
const { width } = Dimensions.get("screen");
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
//const Tab = createBottomTabNavigator();
function ElementsStack(props) {
return (
<Stack.Navigator mode="card" headerMode="screen">
<Stack.Screen
name="Elements"
component={Profile}
options={{
header: ({ navigation, scene }) => (
<Header title="Elements" navigation={navigation} scene={scene} />
),
cardStyle: { backgroundColor: "#F8F9FE" }
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
function ArticlesStack(props) {
return (
<Stack.Navigator mode="card" headerMode="screen">
<Stack.Screen
name="Articles"
component={Articles}
options={{
header: ({ navigation, scene }) => (
<Header title="Articles" navigation={navigation} scene={scene} />
),
cardStyle: { backgroundColor: "#F8F9FE" }
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
function ProfileStack(props) {
return (
<Stack.Navigator initialRouteName="Profile" mode="card" headerMode="screen">
<Stack.Screen
name="Profile"
component={ProfileActivity}
options={{
header: ({ navigation, scene }) => (
<Header
transparent
white
title="Profile"
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#FFFFFF" },
headerTransparent: true
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
function HomeStack(props) {
return (
<Stack.Navigator mode="card" headerMode="screen">
<Stack.Screen
name="Home"
component={HomeActivity}
options={{
header: ({ navigation, scene }) => (
<Header
title="Home"
search
options
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" }
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
export default function OnboardingStack(props) {
return (
<Stack.Navigator mode="card" headerMode="none">
<Stack.Screen
name="Jobs"
component={Results}
option={{
headerTransparent: true
}}
/>
<Stack.Screen name="App" component={AppStack} />
</Stack.Navigator>
);
}
function AppStack(props) {
return (
<Drawer.Navigator
style={{ flex: 1 }}
drawerContent={props => <CustomDrawerContent {...props} />}
drawerStyle={{
backgroundColor: "white",
width: width * 0.8
}}
drawerContentOptions={{
activeTintcolor: "white",
inactiveTintColor: "#000",
activeBackgroundColor: "transparent",
itemStyle: {
width: width * 0.75,
backgroundColor: "transparent",
paddingVertical: 16,
paddingHorizonal: 12,
justifyContent: "center",
alignContent: "center",
alignItems: "center",
overflow: "hidden"
},
labelStyle: {
fontSize: 18,
marginLeft: 12,
fontWeight: "normal"
}
}}
initialRouteName="Home"
>
<Drawer.Screen name="Home" component={HomeStack} />
<Drawer.Screen name="Profile" component={ProfileStack} />
<Drawer.Screen name="Results" component={OnboardingStack} />
<Drawer.Screen name="Elements" component={ElementsStack} />
{/* <Drawer.Screen name="Articles" component={ArticlesStack} /> */}
</Drawer.Navigator>
);
}
So based on the error i would say that validateRouteConfigMap.js is getting an object(routeConfigs) that you've not yet defined or passed in as undefined or you have not set a default value for. Remember Object.keys(ARRAY_OR_OBJECT_VARIABLE) requires a variable of object type (besides null)

Translate react navigation tabBarLabel in react native

I have couple of screens in one of them i have a materialTopTabNavigator with two tabs, i need to translate tab names for different languages.
i tried using useNAvigation and withTranslation but it seems i don't have access to i18next t function to translate.
const Stack = createStackNavigator();
const Router = () => {
const Tab = createMaterialTopTabNavigator();
function MyAdsTabs() {
return (
<Tab.Navigator
tabBarOptions={{
activeTintColor: colors.darkGray,
labelStyle: {fontSize: 12},
style: {backgroundColor: colors.white, borderTopWidth: 0, elevation: 0, shadowOpacity: 0},
}}>
<Tab.Screen
name="MyActiveAds"
component={MyActiveAds}
options={{tabBarLabel: 'MyActiveAds'}}
/>
<Tab.Screen
name="MyDeactiveAds"
component={MyDeactiveAds}
options={{tabBarLabel: 'MyDeactiveAds'}}
/>
</Tab.Navigator>
);
}
function MainStackScreen() {
return (
<Stack.Navigator initialRouteName={'Splash'} headerMode="none">
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Setting" component={Setting} />
<Stack.Screen name="Register" component={Register} />
<Stack.Screen name="Terms" component={Terms} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="EditProfile" component={EditProfile} />
<Stack.Screen name="Search" component={Search} />
<Stack.Screen name="FavouriteAds" component={FavouriteAds} />
<Stack.Screen options={{title: 'My home'}} name="MyAdsTabs" component={MyAdsTabs} />
</Stack.Navigator>
);
}
renderLoading = () => (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>KojaChera</Text>
<ActivityIndicator size="large" color={colors.darkerTeal} />
</View>
);
return (
<Provider store={store}>
<PersistGate persistor={persistor} loading={this.renderLoading()}>
<Root>
<NavigationContainer>
<MainStackScreen />
</NavigationContainer>
</Root>
</PersistGate>
</Provider>
);
};
export default Router;
and this is a part of my package.json:
"react": "16.11.0",
"react-i18next": "^11.3.4",
"react-native": "0.62.2",
"#react-native-community/masked-view": "^0.1.9",
"#react-navigation/material-top-tabs": "^5.1.14",
"#react-navigation/native": "5.2.3",
"#react-navigation/stack": "5.2.18",
"i18next": "^19.4.2",
i solved it by passing i18n as a prop into my router component
const App = () => {
return(
<I18nextProvider i18n={ i18n }>
<Router i18n={ i18n } />
</I18nextProvider>
);
}
and used it this way:
<Tab.Screen name="MyDeactiveAds" component={MyDeactiveAds}
options={{ tabBarLabel: i18n.t('myAds:inActiveAds') }}/>