Translate react navigation tabBarLabel in react native - 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') }}/>

Related

react native navigation nested stack does not match

How to write the code on the back button (on the top left corner) of the calendar page to lead to the HomeCG page? It always leads to the main page. Please help
AuthStack.js
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import Login from "../screens/Login";
import Register from "../screens/Register"
import Forgot from "../screens/Forgot"
import ResetPass from "../screens/ResetPass"
import ConfirmReset from "../screens/ConfirmReset"
import InOutScreen from '../screens/InOutScreen';
import BottomTapCM from "./BottomTapCM";
import BottomTapCG from './BottomTapCG'
import CmCgScreen from '../screens/CmCgScreen';
const Stack = createStackNavigator();
const AuthStack = () => {
return (
<Stack.Navigator screenOptions={{}}>
<Stack.Screen
name="Login"
component={Login}
options={{headerShown: false}}
/>
<Stack.Screen
name="Register"
component={Register}
options={{headerShown: false}}
/>
<Stack.Screen
name="Forgot"
component={Forgot}
options={{headerShown: false}}
/>
<Stack.Screen
name="ResetPass"
component={ResetPass}
options={{headerShown: false}}
/>
<Stack.Screen
name="ConfirmReset"
component={ConfirmReset}
options={{headerShown: false}}
/>
<Stack.Screen
name="BottomTapCM"
component={BottomTapCM}
/>
<Stack.Screen
name="BottomTapCG"
component={BottomTapCG}
options={{headerShown: false}}
/>
<Stack.Screen
name="CmCgScreen"
component={CmCgScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="InOutScreen"
component={InOutScreen}
options={{ title: "ลงชื่อเข้า-ออกงาน" , headerTitleAlign:"center" }}
/>
</Stack.Navigator>
);
};
export default AuthStack;
BottomTapCG.js
import * as React from 'react';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import {useNavigation} from '#react-navigation/native';
import HomeCg from '../screens/HomeCg';
import NotifyNav from './NotifyNav'
import CalendarNav from './CalendarNav';
import EditProfileNav from './EditProfileNav';
import SchCgNav from './SchCgNav';
import { View, Center } from 'native-base'
import { Ionicons ,FontAwesome5 ,AntDesign} from "#expo/vector-icons";
const Tab = createBottomTabNavigator();
export default function BottomTapCG() {
const navigation = useNavigation();
return (
<Tab.Navigator
screenOptions={{ tabBarShowLabel: false ,headerShown: false ,tabBarStyle:{ height: 60,shadowColor: '#000', }}}>
<Tab.Screen name="HomeCg"
component={HomeCg} options={{
tabBarIcon: ({ focused }) => (
<View style={{ top: '-3%'}} >
<Ionicons
name="home-sharp"
size={25}
color={focused ? '#35609C': 'gray'}
></Ionicons>
</View> )}} />
<Tab.Screen
name="CalendarNav"
component={CalendarNav}
options={{
tabBarIcon: ({ focused }) => (
<View style={{ top: '-3%'}} >
<FontAwesome5
name="calendar-alt"
size={25}
color={focused ? '#35609C': 'gray'}
>
</FontAwesome5>
</View> )}} />
<Tab.Screen name="SchCgNav" component={SchCgNav}
options={{
tabBarIcon: ({ focused }) => (
<View style={{ top: '-30%'}} >
<AntDesign
name="pluscircle"
size={50}
color={focused ? '#35609C': 'gray'}
></AntDesign>
</View> )}} />
<Tab.Screen name="NotifyNav" component={NotifyNav} options={{
tabBarIcon: ({ focused }) => (
<View style={{ top: '-3%'}} >
<Ionicons
name="notifications"
size={25}
color={focused ? '#35609C': 'gray'}
></Ionicons>
</View> )}} />
<Tab.Screen name="EditProfileNav" component={EditProfileNav} options={{
tabBarIcon: ({ focused }) => (
<View style={{ top: '-3%'}}>
<FontAwesome5
name="user-alt"
size={25}
color={focused ? '#35609C': 'gray'}
></FontAwesome5>
</View> )}} />
</Tab.Navigator>
);
}
CalendarNav.js
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import CalendarList from '../screens/CalendarList';
const Stack = createStackNavigator();
const CalendarNav = () => {
return (
<Stack.Navigator screenOptions={{}} >
<Stack.Screen
name="CalendarList"
component={CalendarList}
options={{title: "ปฎิทิน" , headerTitleAlign:"center"}}
/>
</Stack.Navigator>
);
};
export default CalendarNav;
Device preview 1:
Device preview 2:
Device preview 3:
Full project:
https://github.com/Naphaporn-Tangai/CEPP-project1

Hiding tab bar with nested navigation

I used nested navigation for my problem. Currently, however, the tab bar is only displayed on pages listed in TabNavigator. Is it possible to display on other pages as well? It is possible to display the tab bar also on screen5. I also have screen6 where I don't want to display the tab bar, so I solve it this way.
App.js
<NavigationContainer
ref={ref}
>
<Navigation />
</NavigationContainer>
Tab.js
const Tab = createBottomTabNavigator();
const Tabs = (props) => {
return(
<Tab.Navigator>
<Tab.Screen name="Screen1" component={Screen1} />
<Tab.Screen name="Screen2" component={Screen2} />
<Tab.Screen name="Screen3" component={Screen3} />
<Tab.Screen name="Screen4" component={Screen4} />
</Tab.Navigator>
);
}
<Stack.Navigator>
<Stack.Group screenOptions={{ headerShown: false }}>
<Stack.Screen name="Screen1" component={Tabs}/>
<Stack.Screen name="Screen2" component={Screen2}/>
<Stack.Screen name="Screen3" component={Screen3}/>
<Stack.Screen name="Screen4" component={Screen4}/>
<Stack.Screen name="Screen5" component={Screen5}/>
<Stack.Screen name="Screen6" component={Screen6}/>
</Stack.Group>
</Stack.Navigator>
Screen4
const Screen4 = ({navigation}) => {
return (
<SafeAreaView>
<Pressable onPress={() => {navigation.navigate('Screen5')}}>
<Text>Screen5</Text>
</Pressable>
</SafeAreaView>
);
}
export default Screen4;
I think you are aksing about this.
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
const HomeNavigator = () => {
<Stack.Navigator>
<Stack.Screen name="Screen1" component={Screen1} />
<Stack.Screen name="Screen2" component={Screen2} />
</Stack.Navigator>;
};
const ProfileNavigator = () => {
<Stack.Navigator>
<Stack.Screen name="Screen3" component={Screen3} />
<Stack.Screen name="Screen3" component={Screen3} />
</Stack.Navigator>;
};
const Tabs = (props) => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeNavigator} />
<Tab.Screen name="Profile" component={ProfileNavigator} />
<Tab.Screen name="YourOtherNavigator" component={YourOtherNavigator} />
</Tab.Navigator>
);
};

How to show tabs AFTER user has logged in (separate navigators)

I want a user to log in BEFORE they are taken to the "Home" screen. Once they hit the home screen, the tabs are shown. I do not want to show the tabs during login/signup.
Here is what I have so far:
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const Switch = createSwitchNavigator();
const AppContainer = createAppContainer();
function AuthNavigation() {
return (
<Stack.Navigator headerMode="none" initialRouteName="Login">
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Signup" component={Signup} />
</Stack.Navigator>
)
}
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Home"
activeColor="#161F3D"
inactiveColor="#B8BBC4">
<Tab.Screen
name="Home"
component={Home}
// options={{
// tabBarIcon: <Icon name="home" size={24} />
// }}
/>
<Tab.Screen
name="Leaderboard"
component={Leaderboard}
// options={{
// tabBarIcon: <Icon name="trophy" size={24} />
// }}
/>
<Tab.Screen
name="Create"
component={Create}
// options={{
// tabBarIcon: <Icon name="add" size={40} />
// }}
/>
<Tab.Screen
name="Notifications"
component={Notification}
// options={{
// tabBarIcon: <Icon name="notifications-circle-outline" size={24} />
// }}
/>
<Tab.Screen
name="Profile"
component={Profile}
// options={{
// tabBarIcon: <Icon name="person" size={24} />
// }}
/>
</Tab.Navigator>
);
}
export default function App() {
return (
<AppContainer>
<Switch.Navigator headerMode="none" initialRouteName="Auth">
<Switch.Screen name="Auth" component={AuthNavigation()} />
<Switch.Screen name="Tabs" component={MyTabs()} />
</Switch.Navigator>
</AppContainer>
);
}
This results in the following error:
TypeError: undefined is not an object (evaluating 'Object.keys(routeConfigs)')
How can I build these two navigators so the auth and the tab navigators are separate?
You only need to pass the reference of the component. You don't need to execute it. It should look like this -
<Switch.Screen name="Auth" component={AuthNavigation} />
<Switch.Screen name="Tabs" component={MyTabs} />

Navigate from a Bottom Tab Navigator to a Stack Navigator

I am building an app with the following dependencies:
"dependencies": {
"#react-navigation/bottom-tabs": "^5.8.0",
"#react-navigation/compat": "^5.2.5",
"#react-navigation/material-bottom-tabs": "^5.2.16",
"#react-navigation/material-top-tabs": "^5.2.16",
"#react-navigation/native": "^5.7.3",
"#react-navigation/stack": "^5.9.0",
"expo": "~38.0.8",
"expo-status-bar": "^1.0.2",
"react": "~16.11.0",
"react-dom": "~16.11.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
"react-native-elements": "^2.0.4",
"react-native-gesture-handler": "^1.7.0",
"react-native-modals": "^0.19.9",
"react-native-reanimated": "^1.10.2",
"react-native-screens": "^1.0.0-alpha.23",
"react-native-web": "~0.11.7",
"react-navigation": "^4.4.0",
"react-navigation-stack": "^2.8.2",
"react-navigation-tabs": "^2.9.0"
},
Let say I have a Stack navigator and a Bottom Tab Navigator. How can I easily navigate from a screen of the bottom tab to a screen of the Stack Navigator?
I found a "solution" which is to add App in my Bottom Tab Navigator, but the problem is it's appearing in the bottom screens, while I dont want that.
Whats the best way to do this?
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer independent={true}>
<Stack.Navigator initialRouteName="Index">
<Stack.Screen name="MyNotes" component={MyNotes} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Signup" component={Signup} />
<Stack.Screen name="Index" component={Index} />
<Stack.Screen name="PasswordForgot" component={PasswordForgot} />
<Stack.Screen name="BottomNavigation" component={BottomNavigation} />
<Stack.Screen name="ProfileParameters" component={ProfileParameters} />
<Stack.Screen name="MyProfile" component={MyProfile} />
</Stack.Navigator>
</NavigationContainer>
);
}
And a Bottom Tab Navigator:
const Tab = createBottomTabNavigator();
const tabActiveColor = "#EF2D56";
const tabInActiveColor = "#898A8D";
const BottomTabNavigator = () => {
return (
<Tab.Navigator
initialRouteName="MyNotes"
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let tabIcon = "../assets/notes.png";
if (route.name === "MyNotes") {
tabIcon = require("../assets/notes.png");
} else if (route.name === "Feed") {
tabIcon = require("../assets/feed.png");
} else if (route.name === "Discover") {
tabIcon = require("../assets/decouvrir.png");
} else if (route.name === "MyProfile") {
tabIcon = require("../assets/myprofile.png");
}
return (
<Image
source={tabIcon}
resizeMode="contain"
style={{
height: 26.4,
width: 22,
tintColor: focused ? tabActiveColor : tabInActiveColor,
}}
/>
);
},
})}
tabBarOptions={{
style: { zIndex: 110 },
safeAreaInset: { bottom: "never" },
activeTintColor: "#000000",
}}
>
<Tab.Screen
name="MyNotes"
component={MyNotes}
options={{
tabBarLabel: "Notes",
}}
/>
<Tab.Screen
name="Feed"
component={Feed}
options={{
tabBarLabel: "Feed",
}}
/>
<Tab.Screen
name="Discover"
component={Discover}
options={{
tabBarLabel: "Découvrir",
}}
/>
<Tab.Screen
name="MyProfile"
component={MyProfile}
options={{
tabBarLabel: "Profil",
}}
/>
<Tab.Screen name="App" component={App} />
</Tab.Navigator>
);
};
export default BottomTabNavigator;
const Stack = createStackNavigator();
export default function BottomNavigation() {
return (
<NavigationContainer independent={true}>
<BottomTabNavigator />
</NavigationContainer>
);
}
Example of Navigation I want to do: Navigate from the MyProfile screen of the Bottom Tab, to the ProfileParameter screen in the stack navigator.
here is a demo: https://snack.expo.io/#nomi9995/1826cf
use only one NavigationContainer and make bottom tabs part of stack navigator then you can easily move from bottom tabs to stack screens
like this
import * as React from 'react';
import { Text, View, Button } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
function TestScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Test!</Text>
</View>
);
}
function HomeScreen(props) {
const gotoTestStackScreen = () => {
props.navigation.navigate('Test');
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button title="Go to test stack screen" onPress={gotoTestStackScreen} />
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Tabs">
<Stack.Screen name="Test" component={TestScreen} />
<Stack.Screen name="Tabs" component={MyTabs} />
</Stack.Navigator>
</NavigationContainer>
);
}

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