Extend an Screen options in react-native - reactjs

i have several screens in stack navigator like below
<Stack.Navigator screenOptions={TransitionScreenOptions}>
<Stack.Screen
options={stackoptions}
name="videoScreen"
component={videoScreen}
/>
<Stack.Screen
options={stackoptions}
name="registerScreen"
component={SignUpScreen}
/>
</Stack.Navigator>
for all the screens i set options like below
const stackoptions = ({ navigation }) => ({
headerBackTitleVisible: false,
headerStyle: {
backgroundColor: "#000",
},
headerTintColor: "#fff",
headerRight: () => {
return (
<Pressable
style={{ paddingRight: 8 }}
onPress={() => navigation.toggleDrawer()}
>
<AntDesign name="menu-fold" size={30} color="white" />
</Pressable>
);
},
});
Now , how can i override or add certain options to one of my screen , for example something like below , I want to modify only headerTintColor , whereas remaining stackoptions should be used except headerTintColor.
<Stack.Screen
options={...stackoptions, headerTitle: "" }
name="registerScreen"
component={SignUpScreen}
/>

for all the screens i set options like below
This is unnecessary. You can specify common options in screenOptions and they'll be applied to all screens, it's not needed to repeat them for every screen. You can use spread operator to merge your TransitionScreenOptions with the others:
<Stack.Navigator screenOptions={({ navigation }) => ({
...TransitionScreenOptions,
headerBackTitleVisible: false,
headerStyle: {
backgroundColor: "#000",
},
headerTintColor: "#fff",
headerRight: () => {
return (
<Pressable
style={{ paddingRight: 8 }}
onPress={() => navigation.toggleDrawer()}
>
<AntDesign name="menu-fold" size={30} color="white" />
</Pressable>
);
},
})}>
You can just do this:
options={{ headerTitle: "" }}
This will override the same option if it was specified in screenOptions
If you need to use the current structure, call the stakOptions function and pass the arguments before spreading it:
options={args => ({
...stackoptions(args),
headerTitle: ""
})}

Related

goBack not working in nested navigators react native. TabNavigator and StackNavigator

I have this problem several days ago and I can't find a solution.
This is my navigation structure
Index.tsx -->
<NavigationContainer>
<Stack.Navigator initialRouteName='tabsBottomHome'
screenOptions={{
headerTitle: () => <Header />,
headerBackground: () => <HeaderBackground />,
headerLeft: ({ onPress, canGoBack }) =>
canGoBack ? (
<Pressable onPress={onPress} style={{ width: 30, height: 15 }}>
<ArrowLeft height={15} width={15} style={{ marginLeft: 15 }} />
</Pressable>
) : (
<Pressable style={{ width: 65, height: 35 }}></Pressable>
),
headerRight: () => <HeaderRight />,
}}
>
{state.isSignIn ? (
<>
<Stack.Screen
name='tabsBottomHome'
component={TabsBottomHome}
options={{headerShown: false }}
/>
</>
) : (
<>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="LoginError"
component={LoginError}
/>
</>
)}
</Stack.Navigator>
</NavigationContainer>
This would be the first navigation of my application. So far everything is going well.
TabsBottomNavigation -->
<Tab.Navigator
initialRouteName='Home'
screenOptions={{
headerShown:true,
tabBarShowLabel:false,
tabBarStyle:style.tabsBottomContainer,
unmountOnBlur: true,
headerTitle: () => <Header />,
headerBackground: () => <HeaderBackground />,
headerLeft: () =>
routeName != "Home" ? (
<Pressable onPress={navigateBack} style={{ width: 65, height: 15 }}>
<ArrowLeft height={15} width={15} style={{ marginLeft: 15 }} />
</Pressable>
)
: (
<Pressable style={{ width: 65, height: 35 }}></Pressable>
)
,
headerRight: () => <HeaderRight />,
}}
sceneContainerStyle={style.backgroundContent}
screenListeners={({route})=>({
state: ()=> {
setRouteName(route.name);
}
})}
backBehavior={'history'}
>
<Tab.Screen
name='Assets'
component={AssetScreen}
options={{tabBarIcon:({focused,color})=>(
<View>
<Image
source={iconAsset}
style={{
tintColor: focused ? '#00B2DF' : '',
marginTop: 8
}}
/>
</View>
)}} />
<Tab.Screen
name='GatewayStack'
component={ConnectGatewayStack}
options={{tabBarIcon:({focused,color})=>(
<View>
<Image
source={iconBluetooth}
style={{
tintColor: focused ? '#00B2DF' : ''
}}
/>
</View>
)}} />
<Tab.Screen
name='Home'
component={HomeScreen}
options={{tabBarIcon:({focused,color})=>(
<View>
<Image
source={iconHome}
style={{
tintColor: focused ? '#00B2DF' : ''
}}
/>
</View>
)
}} />
</Tab.Navigator>
everything is fine here too, the conflict is in the ConnectGatewayStack stack
ConnectGatewayStack -->
export type StackConnectList = {
Connect: undefined;
QRScan: undefined;
GatewayList: undefined;
GatewayInfo: undefined;
NotFoundGateway: undefined;
GatewayDetected: undefined;
ErrorConnecting: undefined;
}
const GatewayStack = createStackNavigator<StackConnectList>();
const ConnectGatewayStack = () =>{
return (
<GatewayStack.Navigator initialRouteName='Connect'
screenOptions={{headerShown:false}}
>
<GatewayStack.Screen name='Connect' component={ConnectScreen} />
<GatewayStack.Screen name='GatewayList' component={GatewayList} />
<GatewayStack.Screen name='GatewayInfo' component={GatewayInfo} />
<GatewayStack.Screen name='QRScan' component={QRScanScreen} />
<GatewayStack.Screen name='NotFoundGateway' component={NotFoundGateway} />
<GatewayStack.Screen name='GatewayDetected' component={GatewayDetected} />
<GatewayStack.Screen name='ErrorConnecting' component={ErrorConnecting} />
</GatewayStack.Navigator>
)
}
export {ConnectGatewayStack};
When I navigate to the ConnectGatewayStack tab, which contains the other components that I just showed, if I go to a child component and press the back button in header, it returns directly to the TabsBottomHome (that is, to the Tabs navigation) and not to the component that was previously visited.
For the navigation back, i use
import { useNavigation } from '#react-navigation/core';
whit
const navigation = useNavigation();
navigation.goback();
I tried whit diferents methods, but none solved my problem.
example test whit
backBehavior={'history'}
backBehavior={'order'}
and many functions of the core react-native and react-native-navigation
any ideas?
sorry for my bad english and thank you very much

React Native Navigation v5 - Whats wrong with my navigation Setup?

I have a problem depending the Navigator setup that is used with Version 5 of React Navigation.
Here is my Code:
import React from "react";
import { LogBox, Platform, TouchableOpacity } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack"
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import {
Auth,
Monatsübersicht2,
StundenChecken,
StundenEintragen,
Logout,
TagesübersichtDiff,
StundenEdit,
MonatsberichtComponent,
} from "../screens/index";
import Icon from "react-native-vector-icons/Ionicons";
import AsyncStorage from "#react-native-async-storage/async-storage";
LogBox.ignoreAllLogs();
const Stack = createStackNavigator();
function EintragenStack() {
return (
<Stack.Navigator initialRouteName="Eintragen">
<Stack.Screen
name="Eintragen"
component={StundenEintragen}
options={{
headerTitle: "Stundenverwaltung",
headerTitleStyle: {
color: "white",
alignSelf: "center",
},
headerStyle: {
backgroundColor: "#a51717",
},
headerRight: () => (
<TouchableOpacity onPress={console.log("unlockUserHandler")}>
<Icon
style={{ paddingRight: 20 }}
size={25}
color="white"
name="lock-open"
/>
</TouchableOpacity>
),
}}
/>
</Stack.Navigator>
)};
function CheckStack(){
return (
<Stack.Navigator initialRouteName="Übersicht" >
<Stack.Screen
name="Übersicht"
component={StundenChecken}
/>
<Stack.Screen
name="Monat"
component={Monatsübersicht2}
options={({navigation}) => ({
title: "Monatsübersicht"
})}
/>
<Stack.Screen
name="Tag"
component={TagesübersichtDiff}
options={({navigation}) => ({
headerRight: () => (
<TouchableOpacity onPress={() => console.log("Ahllo")}>
<Icon
style={{ paddingRight: 20 }}
size={25}
color="#a51717"
name="lock-open"
/>
</TouchableOpacity>
),
title: "Tagesübersicht"
})}
/>
<Stack.Screen
name="Edit"
component={StundenEdit}
options={{
headerTitle: "Stunden bearbeiten",
headerTitleStyle: {
color: "white",
alignSelf: "center",
},
headerStyle: {
backgroundColor: "#F39237",
},
headerRight: () => (
<TouchableOpacity onPress={console.log("unlockUserHandler")}>
<Icon
style={{ paddingRight: 20 }}
size={25}
color="white"
name="lock-open"
/>
</TouchableOpacity>
),
}}
/>
</Stack.Navigator>
)}
const Tab = createBottomTabNavigator();
function Tabs() {
return (
<Tab.Navigator
initialRouteName="Eintragen"
screenOptions={{
backBehavior: "history",
resetOnBlur: true,
tabBarOptions: {
labelStyle: {
fontSize: 12,
color: "black",
},
showIcon : true,
activeTintColor: "red",
activeBackgroundColor: "#ccc",
}
}}>
<Tab.Screen name="Eintragen" component={EintragenStack} options={{ tabBarIcon:() => (<Icon name="add-circle-outline" size={Platform.OS == "ios" ? 30 : 28} color={"green"} />)}}/>
<Tab.Screen name="Übersicht" component={CheckStack} options={{ tabBarIcon:() => (<Icon name="calendar" size={Platform.OS == "ios" ? 30 : 28} color={"black"} />)}}/>
<Tab.Screen name="Monatsbericht" component={MonatsberichtComponent} options={{headerTitle: "Monatsbericht abschließen", tabBarIcon:() => (<Icon name="download" size={Platform.OS == "ios" ? 30 : 28} color={"black"} />)}}/>
<Tab.Screen name="Logout" component={Logout} options={{ tabBarIcon:() => (<Icon name="power" size={Platform.OS == "ios" ? 30 : 28} color={"red"} />)}}/>
</Tab.Navigator>
)
}
const AppNavigator = () => {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
headerLeft: null,
gestureEnabled: false
}}
>
<Stack.Screen name="Auth" component={Auth} />
<Stack.Screen name="Tabs" component={Tabs} />
</Stack.Navigator>
</NavigationContainer>
)
}
export default function App() {
return <AppNavigator/>;
}
Now in my Auth Screen I can navigate to Tabs - so basically Log into the App by calling:
navigation.replace("Tabs");
But when I try to navigate to my CheckStack for example it wont work and I get thrown this error:
The Call: navigation.replace("CheckStack");
The Error:
ERROR The action 'REPLACE' with payload {"name":"CheckStack"} was not handled by any navigator.
Do you have a screen named 'CheckStack'?
So basically the fix is that my "CheckStack" has to be inside the StackNavigator that is used in NavigationContainer - otherwise it wont be able to use navigation inside.
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
headerLeft: null,
gestureEnabled: false
}}
>
<Stack.Screen name="Auth" component={Auth} />
<Stack.Screen name="Tabs" component={Tabs} />
<Stack.Screen name="CheckStack" component={CheckStack} />
</Stack.Navigator>
</NavigationContainer>
the problem is that you are referring to the name of the function and not specifically to the name of the screen
It's screen name
navigation.replace("Tabs");
It's a function not screen name
navigation.replace("CheckStack");

Setting accessibility labels with React.Navigator

I am working on accessibility labels for the voice assistant, I've done most of the tags but I can not set the bottom tab navigator options, how can I use accessibility labels with the below BottomTab.Navigator components?
In the below, I could set the labels with the Icons but it is encapslating limited area.
When I try with Bottom.Navigator, throwing errors something like that:
Error: A navigator can only contain 'Screen' components as its direct children (found 'undefined'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
export default function BottomTabNavigator(): any {
const colorScheme = useColorScheme();
return (
<BottomTab.Navigator
initialRouteName={Routes.TAB_ONE}
tabBarOptions={{
showLabel: false,
inactiveBackgroundColor: Colors[colorScheme].secondaryColor,
activeBackgroundColor: Colors[colorScheme].secondaryColor,
style: {
borderTopWidth: 0,
borderTopColor: 'transparent',
height: 50,
},
}}
>
<BottomTab.Screen
name={Routes.TAB_ONE}
component={TabOneNavigator}
options={{
tabBarIcon: () => (
<View accessible={true} accessibilityLabel="home page">
<CustomIcon name="home" color={Colors[colorScheme].buttonText} />
</View>
),
}}
/>
<BottomTab.Screen
name={Routes.TAB_TWO}
component={TabTwoNavigator}
options={{
tabBarIcon: () => (
<View accessible={true} accessibilityLabel="downloads">
<CustomIcon
name="library"
color={Colors[colorScheme].buttonText}
/>
</View>
),
}}
/>
<BottomTab.Screen
name={Routes.TAB_THREE}
component={TabThreeNavigator}
options={{
tabBarIcon: () => (
<View accessible={true} accessibilityLabel="menu">
<CustomIcon name="menu" color={Colors[colorScheme].buttonText} />
</View>
),
}}
/>
</BottomTab.Navigator>
);
}
Thanks in advance

Remove element from react-native navigation

Just wondering how I can remove the (Back) text in navigation and just use the arrow for navigating I am using react native expo.
<Stack.Screen
name="ChatRoom"
component={ChatRoomScreen}
options={({route}) => ({
title: route.params.name,
headerRight: () => (
<View
style={{
flexDirection: "row",
width: 100,
justifyContent: "space-between",
marginRight: 10,
}}
>
<MaterialIcons name="call" size={22} color={'white'} />
<FontAwesome5 name="video" size={22} color={'white'} />
<MaterialCommunityIcons name="dots-vertical" size={22} color={'white'}/>
</View>
)
})}
/>
I found that react navigation behaves weirdly sometimes. But first, you can try this:
headerBackTitle: ' ',
if that makes the back arrow missing, you can add it manually like so:
headerBackImage: ()=> (<Icon name='chevron-left' color='#FFFFF' onPress={()=>{ navigation.goBack();}} />),
you also need to make sure your options has navigation like so:
options={({route, navigation}) => ({
Note: the Icon i used it from react-native-elements.
You need to
headerBackTitleVisible: false,
add this to options like
options={{
...
headerBackTitleVisible: false,
}}
Proof: https://reactnavigation.org/docs/stack-navigator/#headerbacktitlevisible

How to access the navigation prop in the Stack Navigator's screenOptions attribute?

I want to navigate to a particular screen using a common header button in the stack navigator.
<NavigationContainer>
<RootStack.Navigator
mode="modal"
screenOptions={{
headerTitleAlign: 'center',
headerTitle: () => <SpreeLogo />,
headerRight: (props) => <MaterialIcons style={{
marginHorizontal: 10,
}}
onPress={() => console.log(props)}
name="clear" size={28} color="black" />
}}
>
In the header right icon I would like to have access to the navigation prop. I've tried console logging the prop but there is no prop as navigation. How to get access to it?
As per documentation you can provide a function to screenOptions like below which will give you access to the navigation and from there you should be able to jump to any screen
<NavigationContainer>
<RootStack.Navigator
mode="modal"
screenOptions={({ route, navigation }) => ({
headerTitleAlign: 'center',
headerTitle: () => <SpreeLogo />,
headerRight: (props) => <MaterialIcons style={{
marginHorizontal: 10,
}}
onPress={() => console.log(route, navigation)}
name="clear" size={28} color="black" />
})}
>...
Read the docs here https://reactnavigation.org/docs/stack-navigator and search for screenOptions.
Good Luck
In React Navigation V6 you can provide a function to options
<Stack.Screen
name="Screen"
component={Screen}
options={({ route, navigation }) => ({
headerTitleAlign: "center",
headerLeft: () => (
<Icon
name="arrow-back"
onPress={() => navigation.goBack()}
color="#fff"
size={25}
/>
),
})}
/>

Resources