How to define custom header inside screen in react navigation 5? - javascript

i know we use options prop when we define screen in root file
<Stack.Screen
name="index"
component={Index}
options={({ navigation, route }) => ({
headerRight: (props) => (
<MaterialIcons name="add" size={30} style={{ marginRight: 20 }} />
),
})}
/>
But i want to define in the screen by itself like we used to do in react navigation 4
Index.navigationOptions = () => {
return {
headerRight: (
<MaterialIcons name="add" size={30} style={{ marginRight: 20 }} />
),
};
};
but how i can do it in react navigation 5?

use navigation.setOptions
function HomeScreen({ navigation }) {
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<MaterialIcons name="add" size={30} style={{ marginRight: 20 }} />
),
});
}, [navigation]);

Related

Render header right button conditionally with React Navigation in React Native

I am trying to conditionally render the Entypo new-message icon in the right header based on a boolean variable (if the variable is true, then the icon will show up in the header). Please see the minimum reproducible code below. Thanks in advance.
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import { Ionicons, MaterialCommunityIcons, Entypo } from "#expo/vector-icons";
const Tab = createBottomTabNavigator();
const MainTabNavigator = () => {
return (
<Tab.Navigator
initialRouteName="Chats"
screenOptions={{
tabBarStyle: { backgroundColor: "whitesmoke" },
headerStyle: { backgroundColor: "whitesmoke" },
}}
>
<Tab.Screen
name="Chats"
component={ChatsScreen}
options={({ navigation }) => ({
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="message-processing-outline"
size={size}
color={color}
/>
),
headerRight: () => (
<Entypo
onPress={() => navigation.navigate("Contacts")}
name="new-message"
size={18}
color={"royalblue"}
style={{ marginRight: 15 }}
/>
),
})}
/>
</Tab.Navigator>
);
};
export default MainTabNavigator;
You can do it as below, with a Conditional (ternary) operator. Just replace boleanVariable with your actual variable.
options={({ navigation }) => ({
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="message-processing-outline" size={size} color={color} />
),
headerRight: () =>
!boleanVariable ? (
<></>
) : (
<Entypo
onPress={() => navigation.navigate("Contacts")}
name="new-message"
size={18}
color={"royalblue"}
style={{ marginRight: 15 }}
/>
),
})}

Calling a function from React navigation header (getParam is not a function)

I have this icon that needs to run a function onLogout in a separate file
First I tried passing navigation param to bottomTab options like so
<BottomTab.Screen
name="Settings"
component={Settings}
options={(navigation) => ({
title: "Settings",
tabBarIcon: () => <Icon name="settings" size={20} color="black" />,
headerRight: (
<Icon
onPress={navigation.getParam('onLogout')}
style={{ marginRight: 14 }} name="log-out" size={18} color="black" />
)
})}
/>
In the settings screen where the function lives I have initialized the function like so
this.props.navigation.setParams({ onLogout: this.onLogout });
I have tried inside componentDidMount and componentWillMount
Also tried to bind it
constructor(props) {
super(props);
this.onLogout = this.onLogout.bind(this);
}
TypeError: navigation.getParam is not a function. (In
'navigation.getParam('onLogout')', 'navigation.getParam' is undefined)
At one point the function get executed but without me touching the icon but I changed to this
this.props.navigation.setParams({ onLogout: this.onLogout() });
Since that didn't work I tried writing the options in the file itself
export default class Settings extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerRight: (
<Icon
// onPress={navigation.getParam('onLogout')}
style={{ marginRight: 14 }} name="log-out" size={18} color="black" />
)
};
};
...
No icon shows up on the screen and nothing works with that method (title, ect...)
Try this :
<BottomTab.Screen
name="Settings"
component={Settings}
options={(props) => ({
title: "Settings",
tabBarIcon: () => <Icon name="settings" size={20} color="black" />,
headerRight:() =>(
<Icon
onPress={()=>props.route.params.onLogout()}
style={{ marginRight: 14 }} name="log-out" size={18} color="black" />
)
})}
/>

How to remove the Header from my App? Why is the Header displayed?

How to remove the Header from my App? Why is the Header displayed?
I want to remove the title from the Header, since each page has its own title, and that title takes up space from the screens.
I do not understand why it is displayed. I'm following a tutorial and as many times as I go through, I don't see a way to remove this.
I have followed the official documentation, but I cannot get rid of this nonsensical Header.
The navigation is handled from the AppStack.js file and the Header titles displayed are handled from the <Tab.Navigator> <Tab.Screen /> </Tab.Navigator>, but this is really the bottom tabs, and however, they are also displayed in the Header.
I show some image of what I cannot remove
How do I remove this Header which is unnecessary?
I have the correct dependencies:
"react": "17.0.2",
"react-native": "0.66.1",
"react-native-gesture-handler": "^ 1.10.3",
"react-native-onboarding-swiper": "^ 1.1.4",
"react-native-reanimated": "^ 2.2.3",
"react-native-safe-area-context": "^ 3.3.2",
"react-native-screens": "^ 3.8.0",
"react-native-vector-icons": "^ 8.1.0",
"react-native-webview": "^ 11.14.1",
"styled-components": "^ 5.3.3"
AppStack.js
import React from 'react'
import { View, TouchableOpacity, Text } from 'react-native'
import { createStackNavigator } from '#react-navigation/stack'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import Ionicons from 'react-native-vector-icons/Ionicons'
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5'
import HomeScreen from '../screens/HomeSreen'
import ChatScreen from '../screens/ChatScreen'
import ProfileScreen from '../screens/ProfileScreen'
import AddPostScreen from '../screens/AddPostScreen'
const Stack = createStackNavigator()
const Tab = createBottomTabNavigator()
const FeedStack = ({ navigation }) => (
<Stack.Navigator>
<Stack.Screen
name="Social React Native"
component={HomeScreen}
options={{
headerTitleAlign: 'center',
headerTitleStyle: {
color: '#2e64e5',
fontFamily: 'Kufam-SemiBoldItalic',
fontSize: 18,
},
headerStyle: {
shadowColor: '#fff',
elevation: 0,
},
headerRight: () => (
<View style={{ marginRight: 10 }}>
<FontAwesome5.Button
name="plus"
size={22}
backgroundColor="#fff"
color="#2e64e5"
onPress={() => navigation.navigate('AddPost')}
/>
</View>
),
}}
/>
<Stack.Screen
name="AddPost"
component={AddPostScreen}
options={{
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: '#2e64e515',
shadowColor: '#2e64e515',
elevation: 0,
},
headerBackTitleVisible: false,
headerBackImage: () => (
<View style={{ marginLeft: 15 }}>
<Ionicons name="arrow-back" size={25} color="#2e64e5" />
</View>
),
}}
/>
<Stack.Screen
name="HomeProfile"
component={ProfileScreen}
options={{
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: '#fff',
shadowColor: '#fff',
elevation: 0,
},
headerBackTitleVisible: false,
headerBackImage: () => (
<View style={{ marginLeft: 15 }}>
<Ionicons name="arrow-back" size={25} color="#2e64e5" />
</View>
),
}}
/>
</Stack.Navigator>
)
const ProfileStack = ({ navigation }) => (
<Stack.Navigator>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={{
headerShown: false,
}}
/>
</Stack.Navigator>
)
const AppStack = () => {
const getTabBarVisibility = (route) => {
const routeName = route.state
? route.state.routes[route.state.index].name
: '';
if (routeName === 'Chat') {
return false;
}
return true;
}
return (
<Tab.Navigator
screenOptions={{
activeTintColor: '#2e64e5'
}}>
<Tab.Screen
name="Home"
component={FeedStack}
options={({ route }) => ({
tabBarLabel: 'Home',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="home-outline"
color={color}
size={size}
/>
),
})}
/>
<Tab.Screen
name="Messages"
component={ChatScreen}
options={({ route }) => ({
tabBarVisible: getTabBarVisibility(route),
tabBarIcon: ({ color, size }) => (
<Ionicons
name="chatbox-ellipses-outline"
color={color}
size={size}
/>
),
})}
/>
<Tab.Screen
name="Profile"
component={ProfileStack}
options={{
// tabBarLabel: 'Home',
tabBarIcon: ({ color, size }) => (
<Ionicons name="person-outline" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
)
}
export default AppStack
IMAGES:
you can add options={{ headerShown: false }}
<Tab.Screen
name="Messages"
component={ChatScreen}
options={({ route }) => ({
headerShown: false,
tabBarVisible: getTabBarVisibility(route),
tabBarIcon: ({ color, size }) => (
<Ionicons
name="chatbox-ellipses-outline"
color={color}
size={size}
/>
),
})}
/>

Reactive page using usestate boolean value does not work in Reactnative

I'm making reactive Navigator by using react-native expo
I want to make a code like this
if isLoggedin is false show <LoginContent props={props} />
if isLoggedin is true show <Text>user</Text>
When I did console.log(isLoggedin) the result was undefined
And My code doesn't work even if I change the isLoggedIn value.
This is App.js
import * as React from 'react';...
const Drawer = createDrawerNavigator();
function DrawerNavigate() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
// const changeCheck = () => {
// setIsLoggedIn((isLoggedIn) => !isLoggedIn);
// };
return (
<Drawer.Navigator
screenOptions={{ headerShown: false, headerStyle: { backgroundColor: 'transparent', elevation: 0, shadowOpacity: 0, shadowColor: 'transparent' } }}
drawerContent={(props) => <DrawerContent isLoggedIn={isLoggedIn} changeCheck={changeCheck} {...props} />}
>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Note" component={Note} />
<Drawer.Screen name="CheckedList" component={CheckedList} />
<Drawer.Screen name="UncheckedList" component={UncheckedList} />
<Drawer.Screen name="Support" component={Support} />
<Drawer.Screen name="Setting" component={Setting} />
<Drawer.Screen name="Login" component={Login} />
</Drawer.Navigator>
);
}
function Sidebar() {
return (
<>
<NavigationContainer>
<DrawerNavigate />
</NavigationContainer>
</>
);
}
export default function App() {
return (
<>
<Sidebar style={{ width: 100 }} />
</>
);
}
and this is the part of DrawerContect.js
import * as React from 'react';...
export function DrawerContent(props, { isLoggedIn, changeCheck }) {
const press = () => {
console.log(isLogginedIn);
};
return (
<View style={{ flex: 1 }}>
<DrawerContentScrollView {...props}>
<View style={{ alignItems: 'center', alignContent: 'center' }}>
<View style={{ marginHorizontal: 20, flexDirection: 'column', marginVertical: 20 }}>
<View>{isLoggedIn ? <LoginContent props={props} /> : <Text style={Styles.title}>User</Text>}</View>
</View>
</View>
.
.
.
Whatever variables you have passed in DrawerContent will be accessible in first argument. So you need to destructure first argument which is props to get isLoggedIn.
export function DrawerContent(props) {
const { isLoggedIn, changeCheck } = props; // change this
const press = () => {
console.log(isLogginedIn);
};
return (
<View style={{ flex: 1 }}>
<DrawerContentScrollView {...props}>
<View style={{ alignItems: 'center', alignContent: 'center' }}>
<View style={{ marginHorizontal: 20, flexDirection: 'column', marginVertical: 20 }}>
<View>{isLoggedIn ? <LoginContent props={props} /> : <Text style={Styles.title}>User</Text>}</View>
</View>
</View>

Using a variable for a createDrawerNavigation

I am working on a simple React Native e-commerce app and i ran into a issue. I am trying to add the option to change the language, and it has worked so far with the Redux but now i need to dynamically change the sidebar menu and I cant because it is hardcoded as a prop.The code for the menu is this.
const ShopNavigator = createDrawerNavigator(
{
Produktetee: ProductsNavigator,
Rezervimet: OrdersNavigator,
Postoni: AdminNavigator},
{
contentOptions: {
activeTintColor: MyColors.primary
},
contentComponent: props => {
const {log_out} = useSelector(state => state.language)
const dispatch = useDispatch();
return (
<View style={{ flex: 1, paddingTop: 50 }}>
<SafeAreaView forceInset={{ top: "always", horizontal: "never" }}>
<DrawerItems {...props} />
<Button
title={log_out}
color={MyColors.primary}
onPress={() => {
dispatch(authActions.logOut());
// props.navigation.navigate("Auth");
}}
/>
<View style={{flexDirection: 'row'}}>
<View style={{flex:1 , marginRight:10, marginTop: 5,}} >
<Button
title="English"
type="outline"
color={MyColors.primary}
onPress={()=>{
dispatch(index.selectLanguage(languages.english))
}}
/>
</View>
<View style={{flex:1, marginTop: 5,}} >
<Button
title="Shqip"
type="outline"
color={MyColors.primary}
onPress={()=>{
dispatch(index.selectLanguage(languages.albanian))
}}
/>
</View>
</View>
</SafeAreaView>
</View>
);
}
}
);
I am trying to use the hook, but I can't. If somebody could help me I would be very grateful.

Categories