Pass props though screenstack - react-native

Im trying to pass some props to though an screenstack element in react native. I have a button which onPress will ask for a screen using react navigation like this:
<Button
title="Lees Meer"
color="#d10a10"
onPress={() => RootNavigation.navigate('Article', {
params: { title: title, text: text, image: image },
})}
/>
I want thos params to be used in the article to fill in the text, title and image. I thought I could just use them like this in the article:
function ArticleFull({ navigation, params }) {
return (
<View>
<Header/>
<Card>
<CardItem header bordered>
<Body>
<Image
style={{ width: '100%', height: 400 }}
source={{ uri: 'https://www.holland.com/upload_mm/9/a/b/68638_fullimage_zwolle_sassenpoort.jpg' }}
/>
<Text>
{params.text}
</Text>
</Body>
</CardItem>
</Card>
<Button
title="Go Back"
color="#d10a10"
width= "10%"
onPress={() => navigation.goBack()}
/>
</View>
);
}
export default ArticleFull;
In the app.js i made these screenstacks which is used to navigate to an article but i need it to contain some params which are set in the homepage using the button.
const Stack = createStackNavigator();
App.js:
export default class App extends Component {
render() {
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName="Home" >
<Stack.Screen options={{headerShown: false}} name="Home" component={HomePage} />
<Stack.Screen options={{headerShown: false}} name="Article" component={ArticleFull} />
</Stack.Navigator>
</NavigationContainer>
);
}
}

You can pass like this:-
<Button
title="Go to Details"
onPress={() => {
/* 1. Navigate to the Details route with params */
navigation.navigate('Details', {
itemId: 86,
otherParam: 'anything you want here',
});
}}
/>
and receive like this:-
function DetailsScreen({ route, navigation }) {
/* 2. Get the param */
const { itemId } = route.params;
const { otherParam } = route.params;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
);
}
source
Hope it helps!!!

Related

React component retains previous state

I've been learning React and React Native for less than a week, so there are concepts that I'm still learning.
The code below is a first attempt to code an app with navigation through a bottom tab navigator, more specifically using #react-navigation/material-bottom-tabs and react-native-paper. There are 3 screens called Home, Details and Help. Home and Details both contain a button "ask for help", which will both redirect to the Help screen with a special message that is passed as parameter. For example:
<Button
icon="camera"
mode="contained"
onPress={() => navigation.navigate("Help", { txt: "Everything is OK!" })}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
When loading the application, HelpScreen is initiated with initialParams={{ txt: "nothing" }} and the screen will display You said nothing.
From HomeScreen, clicking on the button redirects me to HelpScreen with onPress={() => navigation.navigate("Help", { txt: "Everything is OK!" })}. Therefore the screen will display You said Everything is OK!.
When moving to another screen and then going back to HelpScreen with the use of the bottom tabs, I expect HelpScreen to be re-rendered with its original value. Therefore I expect the screen to say You said nothing. But no, it still says You said Everything is OK!. The same behavious happens with DetailsScreen with another text.
In the HelpScreen function, I am not saving the parameter to a state. So I don't expect the component to retain the previous value when re-rendering. So why doesn't the component reset to its original value when re-rendering?
Or is it not re-rendering? In which case can you please explain why?
Here is the code:
import { registerRootComponent } from "expo";
import { NavigationContainer } from "#react-navigation/native";
import { NativeStackScreenProps } from "#react-navigation/native-stack";
import { createMaterialBottomTabNavigator } from "#react-navigation/material-bottom-tabs";
import { View } from "react-native";
import { Button, Text } from "react-native-paper";
import { SafeAreaProvider } from "react-native-safe-area-context";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
type NavigationParamList = {
Home: undefined;
Details: undefined;
Help: { txt: string };
};
type PropsHome = NativeStackScreenProps<NavigationParamList, "Home">;
type PropsDetails = NativeStackScreenProps<NavigationParamList, "Details">;
type PropsHelp = NativeStackScreenProps<NavigationParamList, "Help">;
const Tab = createMaterialBottomTabNavigator<NavigationParamList>();
function HomeScreen({ navigation, route }: PropsHome) {
console.log("HOME");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() =>
navigation.navigate("Help", { txt: "Everything is OK!" })
}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function DetailsScreen({ navigation, route }: PropsDetails) {
console.log("DETAILS");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() => navigation.navigate("Help", { txt: "HELP ME!" })}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function HelpScreen({ route }: PropsHelp) {
console.log("HELP");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Text>You said {route.params.txt}</Text>
</View>
);
}
export default function App() {
return (
<SafeAreaProvider>
<NavigationContainer>
<Tab.Navigator initialRouteName="Home" screenOptions={{}}>
<Tab.Screen
name="Home"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
component={HomeScreen}
/>
<Tab.Screen
name="Details"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="alien-outline"
color={color}
size={26}
/>
),
}}
component={DetailsScreen}
/>
<Tab.Screen
name="Help"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="chat-question-outline"
color={color}
size={26}
/>
),
}}
component={HelpScreen}
initialParams={{ txt: "nothing" }}
/>
</Tab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}
registerRootComponent(App);
Note that I have not used the useState hook. I understand that this hook would be needed when one wants the retain a value, not reset it.
React Navigation avoids rerendering each screen every time is focused for both better user experience and avoiding unnecessary screen rerendering.
You should override this default behavior and detect when the screen is revisited/focuses and rerender that screen.
It provided utility hooks to listen to the screen is focused - https://reactnavigation.org/docs/function-after-focusing-screen/
Here code refactor with a solution:
import { registerRootComponent } from "expo";
import {useEffect,useState} from "react"
import { NavigationContainer ,useIsFocused} from "#react-navigation/native";
import { NativeStackScreenProps } from "#react-navigation/native-stack";
import { createMaterialBottomTabNavigator } from "#react-navigation/material-bottom-tabs";
import { View } from "react-native";
import { Button, Text } from "react-native-paper";
import { SafeAreaProvider } from "react-native-safe-area-context";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
type NavigationParamList = {
Home: undefined;
Details: undefined;
Help: { txt: string };
};
type PropsHome = NativeStackScreenProps<NavigationParamList, "Home">;
type PropsDetails = NativeStackScreenProps<NavigationParamList, "Details">;
type PropsHelp = NativeStackScreenProps<NavigationParamList, "Help">;
const Tab = createMaterialBottomTabNavigator();
function HomeScreen({ navigation, route }: PropsHome) {
console.log("HOME");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() =>
navigation.navigate("Help", { txt: "Everything is OK!" })
}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function DetailsScreen({ navigation, route }: PropsDetails) {
console.log("DETAILS");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() => navigation.navigate("Help", { txt: "HELP ME!" })}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function HelpScreen({ route ,navigation}: PropsHelp) {
const [message,setMessage] = useState("")
const isFocused = useIsFocused()
useEffect(()=>{
setMessage(route.params.txt)
return ()=>{
navigation.setParams({txt:"nothing"})
}
},[isFocused])
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Text>You said {message}</Text>
</View>
);
}
export default function App() {
return (
<SafeAreaProvider>
<NavigationContainer>
<Tab.Navigator initialRouteName="Home" screenOptions={{}}>
<Tab.Screen
name="Home"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
component={HomeScreen}
/>
<Tab.Screen
name="Details"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="alien-outline"
color={color}
size={26}
/>
),
}}
component={DetailsScreen}
/>
<Tab.Screen
name="Help"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="chat-question-outline"
color={color}
size={26}
/>
),
}}
component={HelpScreen}
initialParams={{ txt: "nothing" }}
/>
</Tab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}
Working Demo - https://snack.expo.dev/#emmbyiringiro/493761

Maximum depth exceeded: how to define a stack for a tab?

I tried following React-Navigation tutorial to implement Stack Navigator Within a Tab Navigator in React Native application using expo.
I am trying to achieve the following
RootStack (Stack Navigator)
Home (Screen)
Login (Screen)
ConsumerApp (Tab Navigator)
SettingsStackScreen (Stack Navigator)
Settings (Screen)
Details (Screen)
BusinessApp
Orders (screen)
Even when following the tutorial and using the code defined there (as you can see from SettingsStackScreen) I am getting the following error printed over and over again. The BusinessApp works great, because it doesn't have Stack Navigators defined within it, only pure component screen.
ERROR Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator (created by SettingsStackScreen)
in SettingsStackScreen (created by SceneView)
I tried creating the most minimal example possible, so I wasn't sure what else to change/try.
This is root stack navigator in App.js
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} options={{ headerShown: false }} />
<Stack.Screen name="Login" component={LoginScreen} options={{ title: t('Login-s') }}/>
<Stack.Screen name="ConsumerApp" component={ConsumerAppScreen} options={{headerShown: false}}/>
<Stack.Screen name="BusinessApp" component={BusinessAppScreen} options={{headerShown: false}}/>
</Stack.Navigator>
</NavigationContainer>
);
}
The ConsumerAppScreen:
const Tab = createBottomTabNavigator();
export const ConsumerAppScreen = () => {
const { t, i18n } = useTranslation();
function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
const SettingsStack = createNativeStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
return (
<Tab.Navigator
initialRouteName="Settings"
tabBar={(props) => <ConsumerTabBar {...props} />}
>
<Tab.Screen name="Settings" component={SettingsStackScreen} options={{ icon: require("../../assets/dashboard-icon.png"), title: t('Settings') }} />
</Tab.Navigator>
)
}
It's because the way you created ConsumerAppScreen is not correct. Screen components and StackNavigator declarations shouldn't be inside a react component.
(I think the tab bar should have more than one child, but I'm not sure about it.)
The correct implementation:
function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
const SettingsStack = createNativeStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
// tab navigation
const Tab = createBottomTabNavigator();
export const ConsumerAppScreen = () => {
const { t, i18n } = useTranslation();
return (
<Tab.Navigator
initialRouteName="Settings"
tabBar={(props) => <ConsumerTabBar {...props} />}
>
<Tab.Screen name="Settings" component={SettingsStackScreen} options={{ icon: require("../../assets/dashboard-icon.png"), title: t('Settings') }} />
</Tab.Navigator>
)
}

I created a background component with a picture

I created a background component with a picture. I want to use it in Navigator for all screens but I get error Error: A navigator can only contain 'Screen', 'Group' or 'React.Fragment' as its direct children (found 'BackgroundImage'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
return (
<BackgroundImage>
<Stack.Navigator
screenOptions={{
headerStyle: { backgroundColor: Colors.header },
headerTintColor: 'white',
contentStyle: { backgroundColor: Colors.primary100 },
}}
>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Register" component={RegisterScreen} />
</Stack.Navigator>
</BackgroundImage>
);
}
My component
const image = require('../assets/background/home.png');
const BackgroundImage = ({children}) => (
<ImageBackground source={image} style={styles.image}>
{children}
</ImageBackground>
);
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
image: {
flex: 1,
justifyContent: 'center'
}
});
export default BackgroundImage;
I this case is works
function HomeScreeen() {
return (
<BackgroundImage>
<View style={styles.rootContainer}>
<Image source={logo} />
<Text style={styles.title}>Test!</Text>
</View>
</BackgroundImage>
);
}
#superDev1117 I use NavigationContener in this file and I get "Error: Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, pass 'independent={true}' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them."
function Navigation() {
const authCtx = useContext(AuthContex);
return (
<NavigationContainer>
{!authCtx.isAuthenticated && <AuthStack />}
{authCtx.isAuthenticated && <AuthenticatedStack />}
</NavigationContainer>
You can't use BackgroundImage component in this case.
Try with this:
on Root component,
<BackgroundImage>
<NavigationContainer> // from '#react-navigation/native';
<Stack.Navigator
...
/>
</NavigationContainer>
</BackgroundImage>

Navigation back click event in React Native

I am working on a React Native application. I am using navigation in my application. I want to do something when user presses back navigation i.e. moved to a back screen.
How can i get the click event of "blacked circle Frage" in the above image. I am working on IOS
Use a custom header with
import { Header } from "native-base";
And add below code in your route file to disable default header.
navigationOptions: {
header: null
}
my custome header code for your reference
<Header style={styles.header}>
<View style={{ flex: 2 }}>
<TouchableOpacity
style={styles.iconButton}
onPress={() => { this.createNote(); this.props.navigation.navigate('Home') }}>
<Icon name="arrow-back" size={28} color="#606060" />
</TouchableOpacity>
</View>
<View style={{ flex: 8 }}></View>
<View style={{ flex: 2 }}>
<TouchableOpacity
style={styles.iconButton}
onPress={() => { this.createNote(); this.props.navigation.navigate('Home') }}>
<Icon name="check" size={28} color="#606060" />
</TouchableOpacity>
</View>
</Header>
reference link:- https://www.npmjs.com/package/native-base
It probably varies depending on the libraries you are using. I am using react-native-paper in Expo, which uses the headerLeft option in the Stack.Screen component. Here's a complete example - save it and then 'expo start'
import { Provider as PaperProvider, Text } from 'react-native-paper'
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<PaperProvider>
<NavigationContainer >
<Stack.Navigator>
<Stack.Screen
name="Example"
options={{
title: 'Example',
headerLeft: () => <Text>Custom left button</Text>,
}}
component={() => <Text>Example body text</Text>}
/>
</Stack.Navigator>
</NavigationContainer>
</PaperProvider>
)
}
You can use onPress={() => this.props.navigation.goBack()} on TouchableOpacity if you are redirecting to the previous page
Also you can use this.props.navigation.navigate('Any_Screen') to move to other screens.
Also, I would like to suggest you to get familiar with BackHandler to move back to previous page when hardware back button is pressed.
add the code
onClick={this.props.navigation.goBack()}
or use specif navigation replace go back to
onClick={this.props.navigation.navigate('namepagespacific')}
check this screen there are mutiple example of handling click event
import React from 'react';
import { View, Text, StyleSheet, Button} from 'react-native';
class DetailsScreen extends React.Component {
static navigationOptions = ({ navigation, navigationOptions, screenProps }) => {
return {
title: navigation.getParam('title', 'A Nested Details Screen'),
};
};
render() {
const { navigation } = this.props;
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');
return (
<View style={styles.detailsScreen}>
<Text>Details Screen</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Button
title="Go to Details... again"
onPress={() => this.props.navigation.push('Details')}
/>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.popToTop()}
/>
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({ title: 'Updated!' })}
/>
<Button
title="Modal"
onPress={() => this.props.navigation.navigate('MyModal')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
detailsScreen: {
flex: 1,
alignItems: "center",
justifyContent: "center"
}
})
export default DetailsScreen;
things you have asked in the comment section I could not find any exact answer for your question but you can take a look into this url how header buttons work
https://snack.expo.io/#react-navigation/simple-header-button-v3
hope this will work for you
header: ({ goBack }) => ({
left: ( <Icon name={'chevron-left'} onPress={ () => { goBack() } } /> ),
}),
you can also follow this page https://github.com/react-navigation/react-navigation/issues/779

Why Header component in NativeBase is not on top?

i got a little problem with Header component in NativeBase (UI Component for React Native). Its position should be on top. But, mine is below a white block. I don't know why its there.
Here my code
import React, { Component } from 'react';
import { Image } from 'react-native';
import {
Container,
Header,
Left,
Body,
Right,
Title,
Content,
Footer,
FooterTab,
Button,
Icon,
Text,
List,
ListItem,
Switch,
Item,
Input,
Form,
DeckSwiper,
Card,
CardItem,
Thumbnail,
View
} from 'native-base';
import { Col, Row, Grid } from "react-native-easy-grid";
import { StackNavigator } from 'react-navigation';
import Expo from "expo";
import { cards, groups_category } from '../data/dummies';
class HomeScreen extends Component {
constructor (props) {
super(props);
this.state = {
loading: true,
isUserLogin: false,
searchStatus: false
}
this.showSearch = this.showSearch.bind(this);
this.checkLoginStatus = this.checkLoginStatus.bind(this);
}
async componentWillMount() {
await Expo.Font.loadAsync({
'Roboto': require('native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
'Ionicons': require("#expo/vector-icons/fonts/Ionicons.ttf")
});
this.setState({ loading: false });
}
showSearch () {
this.setState({ searchStatus: !this.state.searchStatus });
}
checkLoginStatus () {
if (!this.state.isUserLogin) {
return this.props.navigation.navigate('Login');
} else {
return
}
}
render() {
if (this.state.loading) {
return <Expo.AppLoading />;
}
return (
<Container>
{ this.state.searchStatus &&
(<Header searchBar rounded>
<Item regular>
<Icon name='md-arrow-back' onPress={this.showSearch} />
<Input placeholder='Contoh: Jakarta Memancing'/>
<Icon name='search' />
</Item>
</Header>)
}
{ !this.state.searchStatus &&
(<Header>
<Left>
<Icon name='add' style={{color: '#FFFFFF'}} />
</Left>
<Body style={{ alignItems: 'center' }}>
<Title>Komunitas</Title>
</Body>
<Right>
<Icon name='search' style={{color: '#FFFFFF'}} onPress={this.showSearch} />
</Right>
</Header>)
}
{/* Content */}
<Content padder={true}>
<View style={{height: 470}}>
<DeckSwiper
dataSource={cards}
renderItem={item =>
<Card style={{ elevation: 3 }}>
<CardItem>
<Left>
<Thumbnail source={item.image} />
<Body>
<Text>{item.text}</Text>
<Text note>NativeBase</Text>
</Body>
</Left>
</CardItem>
<CardItem cardBody>
<Image style={{ height: 300, flex: 1 }} source={item.image} />
</CardItem>
<CardItem>
<Icon name="heart" style={{ color: '#ED4A6A' }} />
<Text>{item.name}</Text>
</CardItem>
</Card>
}
/>
</View>
<List>
<ListItem itemHeader first>
<Text>Kategori Grup</Text>
</ListItem>
{groups_category.map(group => {
return (<ListItem key={group.id}>
<Left>
<Icon name={group.icon}/>
</Left>
<Body>
<Text>{group.name}</Text>
</Body>
<Right />
</ListItem>)
}
)}
</List>
</Content>
{/* Content */}
<Footer>
<FooterTab>
<Button vertical active>
<Icon active name="home" />
<Text style={{fontSize: 9.5}}>Home</Text>
</Button>
<Button vertical>
<Icon name="megaphone" />
<Text style={{fontSize: 9.5}}>Baru</Text>
</Button>
<Button vertical>
<Icon name="notifications" />
<Text style={{fontSize: 9.5}}>Notifikasi</Text>
</Button>
<Button onPress={this.checkLoginStatus} vertical>
<Icon name="person" />
<Text style={{fontSize: 9.5}}>Profil</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
export default HomeScreen;
It results like this
As you can see the Header which has search icon is located below an empty space / white color. Why this happen ? Maybe there are a lot of friends here had experienced it before when using NativeBase UI Component.
It's because you are using StackNavigator as well. You can disable the header as below.
static navigationOptions = {
headerMode: 'none'
}
UPDATE for React Navigation 5.x
If you want to use Nativebase's header with react navigation 5, you can do it like this:
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import {
Header,
Left,
Body,
Title,
Button,
Icon,
View,
Text
} from 'native-base';
const Stack = createStackNavigator();
const Home = () => {
return (
<View>
<Text>Hello World</Text>
</View>
)
}
const CustomHeader = ({scene, previous, navigation}) => {
const {options} = scene.descriptor;
const title =
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
? options.title
: scene.route.name;
return (
<Header>
<Left>
{previous ? (
<Button transparent onPress={navigation.goBack}>
<Icon name="arrow-back" />
</Button>
) : (
undefined
)}
</Left>
<Body>
<Title>{title}</Title>
</Body>
</Header>
);
};
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={Home}
options={{
header: (props) => <CustomHeader {...props} />,
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
More of the options here https://reactnavigation.org/docs/en/stack-navigator.html
Set header null in navigation option to remove top blank space, like below
export default class Home extends React.Component {
static navigationOptions = {
title: 'Home',
header: null //used for removing blank space from top
};
}