react navigation own header component - react-native

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!!

Related

React native : bottom navigation with dynamic initialRouteName implementation

I am a beginner in react native. I have gone through different related topics. But failed. This is my issues,
I have a bottom navigator with 4 items, say Dashboard, X, Patient and Y. Here is the optimised bottom navigator code.
const Stack = createStackNavigator();
const Bottom = createBottomTabNavigator();
const Main = () => {
return (
<Bottom.Navigator
initialRouteName="DashboardScreenStack"
tabBarOptions={{
style: {
height: 70,
paddingTop: 20,
backgroundColor: '#F3F6FF',
},
activeTintColor: colors.navigationTextActive,
inactiveTintColor: colors.navigationTextInactive,
labelStyle: {
fontSize: 15,
marginTop: 15,
paddingBottom: 10,
},
}}>
<Bottom.Screen
name="DashboardScreenStack"
component={DashboardScreenStack}
options={{
tabBarLabel: 'Dashboard',
}}
/>
<Bottom.Screen
name="X"
component={X}
options={{
tabBarLabel: 'X',
}}
/>
<Bottom.Screen
name="Patient"
component={Patient}
options={{
tabBarLabel: 'Patient',
}}
/>
<Bottom.Screen
name="Y"
component={Y}
options={{
tabBarLabel: 'Y',
}}
/>
</Bottom.Navigator>
);
};
This is my code for Patient menu.
const Patient = (props) => {
let resultData = null;
var initialRoute = '';
if (
typeof props.route.params != 'undefined' &&
props.route.params.result != null
) {
resultData = props.route.params.result;
initialRoute = 'PatientDashboardScreen';
} else {
initialRoute = 'AddPatientScreen';
}
return (
<Stack.Navigator
initialRouteName={initialRoute }>
<Stack.Screen
name="PatientDashboardScreen"
component={PatientDashboardScreen}
initialParams={resultData}
options={{headerShown: false}}
/>
<Stack.Screen
name="TestScreen1"
component={TestScreen1}
options={{headerShown: false}}
/>
<Stack.Screen
name="TestScreen2"
component={TestScreen2}
options={{headerShown: false}}
/>
<Stack.Screen
name="AddPatientScreen"
component={AddPatientScreen}
options={{headerShown: false}}
/>
</Stack.Navigator>
);
};
There are 4 screens that should be shown in Patient menu. Out of those if I am selecting an item in my Dashboard menu I need to open "PatientDashboardScreen". And there will be some data available in props too. But on directly clicking 'Patient' menu, I need to move to "AddPatientScreen" where no data is passed.
I tried the above code. But only the initial click works. If I am selecting from list first, the always Patient menu is showing "PatientDashboardScreen" and if I am selecting Patient menu directly first, then always "AddPatientScreen" is shown on Patient menu selection.
Any help would be greateful. Thank you
Based on your question
You have a bottom navigator and one of the screens has a nested stack navigator.
The requirement here is to show a specific screen when pressing the bottom navigator button and redirect to a screen when opening from another screen in bottom navigator along with some parameters.
This is one way to do this.
<Tab.Screen
name="Hospital"
component={HospitalView}
options={({ navigation }) => ({
tabBarButton: (props) => (
<TouchableOpacity
{...props}
onPress={() =>
navigation.navigate('Hospital', { screen: 'Patient' })
}
/>
),
})}
/>
You can have a custom onPress in your bottom navigator button which will use the navigate with the screen option which will take you to the specific screen.
To navigate from another screen with parameters you can use the below option
<Button
title="Doctor"
onPress={() =>
navigation.navigate('Hospital', {
screen: 'Doctor',
params: { name: 'Doc 1' },
})
}
/>
Your full code should look something similar to this
const Stack = createStackNavigator();
function Patient() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Patient Screen</Text>
</View>
);
}
function Doctor({route}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Doctor Screen</Text>
<Text>{route?.params?.name}</Text>
</View>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button
title="Doctor"
onPress={() =>
navigation.navigate('Hospital', {
screen: 'Doctor',
params: { name: 'Doc 1' },
})
}
/>
</View>
);
}
function HospitalView() {
return (
<Stack.Navigator>
<Stack.Screen name="Doctor" component={Doctor} />
<Stack.Screen name="Patient" component={Patient} />
</Stack.Navigator>
);
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen
name="Hospital"
component={HospitalView}
options={({ navigation }) => ({
tabBarButton: (props) => (
<TouchableOpacity
{...props}
onPress={() =>
navigation.navigate('Hospital', { screen: 'Patient' })
}
/>
),
})}
/>
</Tab.Navigator>
);
}
You can refer this sample
https://snack.expo.io/#guruparan/5f3f1d

'focus' listener not calling every time. React Native

I am new in react native technology. I have used following hierarchy in my react native app.
I have used Stack.Navigator in which I am using various screen, I. Login, II. Sign-Up, III. TabBar Screen.
In TabBar screen I have used various individual Stack.Navigator because I have to show tab bar on every child screen.
Now problem is that I have to update some value on tab screen when user click on that particular screen. It is calling once at first time, not working second time.
I have used following code for execute 'focus' listener on tab screen :-
onScreenFocus = () => {
this.reloadFavrouite()
alert("again calling")
}
componentDidMount() {
this.props.navigation.addListener('focus', () => this.onScreenFocus())
this.reloadFavrouite()
}
'focus' listener work well If I am not use individual Stack.Navigator at every tab screen, but it is creating another issue is that tab bar not showing in child screen.
I have used this tab navigator code:- Please check
export default class TabNavigator extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Tab.Navigator initialRouteName='Home' lazy={true} tabBarOptions={
{
style: {
backgroundColor: '#FFFFFF',
borderTopLeftRadius: 25,
borderTopRightRadius: 25,
overflow: 'hidden',
borderColor: 'transparent',
}
}
}>
<Tab.Screen name="HomeNavigator" component={HomeNavigator}
options={{
tabBarLabel: ({ focused }) => {
const tintColortab = focused ? "#006C35"
: "#000000"
return (
<Text style={{ color: tintColortab, fontSize: 8, fontFamily: "Roboto-Bold", marginBottom: 6 }}>{StringsOfLanguages.Home}</Text>
)
},
tabBarIcon: ({ focused }) => {
const tintColortab = focused ? "#006C35"
: "#000000"
return (
<Image source={require('../../../assets/images/TabBarIcons/ic_home_selected/ic_home_selected.png')}
style={{ marginTop: 10, tintColor: tintColortab }}>
</Image>
)
}
}}>
</Tab.Screen>
<Tab.Screen name="FavouriteNavigator" component={FavouriteNavigator}
options={{
tabBarLabel: ({ focused }) => {
const tintColortab = focused ? "#006C35"
: "#000000"
return (
<Text style={{ color: tintColortab, fontSize: 8, fontFamily: "Roboto-Bold", marginBottom: 6 }}>{StringsOfLanguages.Favorite}</Text>
)
},
tabBarIcon: ({ focused }) => {
const tintColortab = focused ? "#006C35"
: "#000000"
return (
<Image source={require('../../../assets/images/TabBarIcons/ic_favorits_unselected/ic_favorite_unselected.png')}
style={{ marginTop: 10, tintColor: tintColortab }}>
</Image>
)
}
}}
>
</Tab.Screen>
</Tab.Navigator>
);
}
And individual navigation is like :-
class HomeNavigator extends React.Component {
render() {
return (
<NavigationContainer independent={true}>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} options={{ headerShown: false }} />
<Stack.Screen name="AllRestuarent" component={AllRestuarent} options={{ headerShown: false }} />
<Stack.Screen name="AllLaundry" component={AllLaundry} options={{ headerShown: false }} />
<Stack.Screen name="AllEntertainment" component={AllEntertainment} options={{ headerShown: false }} />
<Stack.Screen name="Offer" component={Offer} options={{ headerShown: false }} />
<Stack.Screen name="ComponyMap" component={ComponyMap} options={{ headerShown: false }} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
class FavouriteNavigator extends React.Component {
render() {
return (
<NavigationContainer independent={true}>
<Stack.Navigator>
<Stack.Screen name="Favorites" component={Favorites} options={{ headerShown: false }} />
<Stack.Screen name="Offer" component={Offer} options={{ headerShown: false }} />
<Stack.Screen name="ComponyMap" component={ComponyMap} options={{ headerShown: false }} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
You are not using focus listener in the right way according to your current version, You are using react-navigation v5 and you are adding a listener the way it is used in react-navigation v4, Here is a solution to your problem.
class YourClassComopnent extends React.Component {
componentDidMount() {
/*
Now you can access to isFocused prop and
this prop will be true whenever your screen is
in the focus.
*/
if(this.props.isFocused) this.onScreenFocus()
this.reloadFavrouite()
}
render() {
// Get it from props
const { isFocused } = this.props;
}
}
// Wrap and export
export default function(props) {
const isFocused = useIsFocused();
// pass your class here
return <YourClassComopnent {...props} isFocused={isFocused} />;
}
Link to docs, how you can use isFocused in react-navigation v5

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)

how to handle react-navigation custom header back Button

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>
);
}

How can I change the title for each screen inside TabNavigator? - React Navigation

My stack navigator
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="PageA" component={PageA} options={{title:'Page=A'}} />
<Stack.Screen name="PageB" component={PageB} options={{title:'Page=B'}} />
<Stack.Screen name="Menu" component={MenuTabNavigator} options={{title:'Menu'}} />
</Stack.Navigator>
</NavigationContainer>
and my tab navigator
const MenuTabNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name="PageA" component={PageA} />
<Tab.Screen name="PageB" component={PageB} />
<Tab.Screen name="Menu" component={Menu} />
</Tab.Navigator>
);};
I'm using Tab Navigator with Stack Navigator.
ScreenA, Screen B and Menu screen in my Tabs.
I pass MenuTabNavigator to StackNavigator's Menu Component as you can see.
Problem:
When I use tabs, header title stays 'Menu'.
For example when I touch to PageB on tab, i expect header title should be 'PageB' but it stays 'Menu'.
How can I change header title for screens when i use bottom tabs?
The approach you are using is wrong. if you go this way you have to create three StackNavigators so that you can get three different headers. and then wrap them in a tab navigator. but this is the wrong way to use it.
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
function HomeScreen({ navigation }) {
navigation.setOptions({ title: 'Home' })
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
function SettingsScreen({ navigation }) {
navigation.setOptions({ title: 'Setting' })
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
function Menu({ navigation }) {
navigation.setOptions({ title: 'Menu' })
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Menu</Text>
</View>
);
}
const StackHome = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
);
};
const StackSetting = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Setting" component={SettingsScreen} />
</Stack.Navigator>
);
};
const StackMenu = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Menu" component={Menu} />
</Stack.Navigator>
);
};
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="PageA" component={StackHome} options={{ title: "Home" }} />
<Tab.Screen name="PageB" component={StackSetting} options={{ title: "Settings"
}}
/>
<Tab.Screen name="Menu" component={StackMenu} options={{ title: "Menu" }} />
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;