How to get header button in react native - react-native

I have created a different class for navigation to maintain the state of loggedIn and loggedOut user as follows:-
import React from "react";
import { createStackNavigator, createSwitchNavigator, DrawerNavigator } from "react-navigation";
import DrawerContent from "../views/Sidebar"
import Profile from '../views/Profile';
import Extra from '../views/Extra';
import SignIn from '../views/SignIn';
import Home from '../views/Home';
import Info from '../views/Info';
import Logout from '../views/Logout';
export const SignedIn = createStackNavigator({
Home: {
screen: Home,
},
Profile: {
screen: Profile,
},
Extra: {
screen: Extra,
}
});
export const SignedOut = createStackNavigator({
SignIn: {
screen: SignIn,
navigationOptions: {
title: "Sign Up",
headerRight: <Text>Hi</Text> //calling this gives an error
}
},
});
export const RootNavigator = (signedIn = false) => {
return createSwitchNavigator(
{
SignedIn: {
screen: SignedIn,
navigationOptions: {
gesturesEnabled: false
}
},
SignedOut: {
screen: SignedOut,
navigationOptions: {
gesturesEnabled: false
}
}
}, {
headerMode: "none",
mode: "modal",
initialRouteName: signedIn ? "SignedIn" : "SignedOut"
}
);
};
I want to create a button in navigation bar on signUp screen but it is giving an error like :-
header Title is easily shown onto screen but the right and left button doesn't seems to be appear. Any help on this.

Your header button must be a component
The way you are using is not pointing to a valid component
To do that either create a new component 'HeaderRight' and import it like you did for the 'Home' component,then point your headerRight property to it
Like headerRight:HeaderRight
Or simply wrap your text element within parenthesis like this
headerRight:(<Text>Hi</Text>)
Try and tell me if it is solved
Best regards

Related

Pass parameters between drawer stacks react-navigation

My router setup is as below
import { createAppContainer, createDrawerNavigator, createStackNavigator, createSwitchNavigator } from "react-navigation";
import Home from "./components/Home";
import Search from "./components/Search";
import Map from "./components/Map";
import Login from "./components/Login";
import ForgotPassword from "./components/ForgotPassword";
import SideMenu from "./SideMenu";
const DashboardStack = createStackNavigator(
{
Home: { screen: Home },
Search : {screen : Search}
}
);
const MapStack = createStackNavigator(
{
Map: { screen: Map },
}
);
const AuthStack = createStackNavigator(
{
Login: { screen: Login },
ForgotPassword: { screen: ForgotPassword },
}
);
export const DrawerStack = createDrawerNavigator(
{
Dashboard: { screen: DashboardStack },
Map: { screen: MapStack },
},
{
contentComponent: SideMenu,
drawerWidth: 250
}
);
export const AppNavigator = createStackNavigator(
{
Drawer: { screen: DrawerStack },
Auth: { screen: AuthStack },
},
{
// initialRouteName: "Drawer",
headerMode: 'none',
mode: 'modal',
}
);
export default createAppContainer(DrawerStack);
Everything working fine, just a small issue. When I navigate to search screen from home and then switch to the Map screen with parameters, those parameters are not reaching to the Map screen.
My current setup is at codepan
Your problem is that your MapStack and your Map screen both have the same name, 'Map'.
Just replace the MapStack route to something else like 'MapStack' and you'll get the params.
See here: https://snack.expo.io/SyTFUPZUB
export const DrawerStack = createDrawerNavigator(
{
Dashboard: { screen: DashboardStack },
MapStack: { screen: MapStack },
},
{
contentComponent: SideMenu,
drawerWidth: 250
}
);
#sfratini is right
The issue is indeed "Map" key being present in two places.
So navigation.navigate("Map") will navigate to MapStack.
Navigating to stack means going to current screen of that stack which defaults to initialRouteName or first screen in the stack.
To verify this, add another screen as first screen in MapStack and check the behaviour.
So, solution to your issue is to rename "Map" key to something else, as suggested by #sfratini.
It works fine by just adding map screen to dashboard stack
const DashboardStack = createStackNavigator(
{
Home: { screen: Home },
Search : {screen : Search},
Map: { screen: Map }
}
);
then use
this.props.navigation.getParam('name', 'name is coming')
to get the name params value
here is the code
https://snack.expo.io/HyEFZeyLB
you can reach the parameters in your Map screen like following:
update this :
render() {
return (
<SafeAreaView style={styles.container}>
<Text>Map</Text>
</SafeAreaView>
)
}
to this :
render() {
return (
<SafeAreaView style={styles.container}>
<Text>{this.props.navigation.state.params.name}</Text>
</SafeAreaView>
)
}
and you have to put your Map screen in with home and search Stack like following:
import { createAppContainer, createDrawerNavigator, createStackNavigator,
createSwitchNavigator } from "react-navigation";
import Home from "./components/Home";
import Search from "./components/Search";
import Map from "./components/Map";
import Login from "./components/Login";
import ForgotPassword from "./components/ForgotPassword";
import SideMenu from "./SideMenu";
const DashboardStack = createStackNavigator(
{
Home: { screen: Home },
Search : {screen : Search},
Map: { screen: Map },
}
);
const AuthStack = createStackNavigator(
{
Login: { screen: Login },
ForgotPassword: { screen: ForgotPassword },
}
);
export const DrawerStack = createDrawerNavigator(
{
Dashboard: { screen: DashboardStack },
},
{
contentComponent: SideMenu,
drawerWidth: 250
}
);
export const AppNavigator = createStackNavigator(
{
Drawer: { screen: DrawerStack },
Auth: { screen: AuthStack },
} ,
{
// initialRouteName: "Drawer",
headerMode: 'none',
//mode: 'modal',
}
);
export default createAppContainer(DrawerStack);
the result from your snak :
hope this will help.

createMaterialTopTabNavigator not rendring properly in one screen in react native

I am implementing createMaterialTopTabNavigator in one screen but nothing is rendering in my app. i am returning MainNavigator which is app container of this screen. am i making mistake to use to app containers or not ? if it is mistake then please guide me how to work with proper flow in react navigation like in app using drawer navigator ,bottom navigator and top navigator at same time.
App Flow :
MainScreenNavigation > MainJobScreen >
MainScreenNavigation code:
import React from "react";
import {createStackNavigator, createAppContainer} from "react-navigation";
import {Signin} from "../screens/Signin";
import {Splash} from '../screens/Splash';
import {HomeScreen} from '../screens/Home/HomeScreen'
import {Profile} from '../screens/Profile/Profile'
import {Notifications} from '../screens/Notifications/Notifications'
import {MainJobScreen} from '../screens/JobFeed/MainJobScreen'
export const MainScreenNavigation = createAppContainer(createStackNavigator({
Home: {
screen: Splash
},
Signin: {
screen: Signin
},
HomeScreen: {
screen: HomeScreen
},
Profile: {
screen: Profile
},
Notifications: {
screen: Notifications
},
JobFeed: {
screen: MainJobScreen
}
}));
;
MainJobScreen code: acutaly where i am using createMaterialTopNavigator
import React from 'react'
import {createMaterialTopTabNavigator,createAppContainer,createStackNavigator } from 'react-navigation'
import { AllTab } from './AllTab'
import { ActiveTab} from './ActiveTab'
import { CompletedTab } from './CompletedTab'
import { JobScreen} from './JobScreen'
const TabNavigator = createMaterialTopTabNavigator({
TabOne: AllTab,
TabTwo: ActiveTab,
TabThree: CompletedTab,
},
{
initialRouteName: 'TabOne',
tabBarOptions: {
style: {
backgroundColor: 'red'
}
},
tabBarPosition: 'top',
swipeEnabled: true,
animationEnabled: true,
})
TabNavigator.navigationOptions={
headerTitle: 'JobFeed'
}
const MainNavigator= createAppContainer(createStackNavigator({
Tabs: TabNavigator,
MainScreen: JobScreen,
},{
initialRouteName: 'MainScreen'
}))
export class MainJobScreen extends React.Component{
static navigationOptions = {
headerTitle: 'JobFeed'
}
render(){
return(
<MainNavigator />
)
}
}
Help will be highly appreciated
Thanks in advance
Mixing the Nav Stacks is your solution here brother.
You have to put the tab navigator inside of your main navigator!
and when the navigation stack hits the TabScreen it will show up the first default screen of the tab navigator you have created.
//....your imports
export const MainScreenNavigation = createAppContainer(createStackNavigator({
Home: {
screen: Splash
},
Signin: {
screen: Signin
},
HomeScreen: {
screen: HomeScreen
},
Profile: {
screen: Profile
},
Notifications: {
screen: Notifications
},
JobFeed: {
screen: MainJobScreen
},
JobFeed: {
screen: MainJobScreen
},
TabScreen: {
screen: TabNavigator //------> add this in your main navigator
}
}));
;
now the stack should go like this!
a file exporting your main navigatior which should be used in your App.js
and in that navigation stack your Tabnavigation stack should be added like you add any other screen or so as shown in code
NOTE ! you should be separately exporting the TabScreen Navigator from a file! and if you are using the navigator in your code file MainScreen then that main Screen should be in the Tab navigation stack's first screens!

Using Tab and Stack Navigator Together

I am building an App on React-Native for which I am using React-Navigation
Now, Inside that i am using Stack-Navigation and TabNavigator (updated it DrawerNavigator)
import {
createStackNavigator,
TabNavigator,
DrawerNavigator
} from 'react-navigation';
import CoinCapCharts from "./src/container/CoinCapCharts.js"
import CoinCap from './src/container/CoinCap.js';
//THis is being Exported to App.js
export const Tab = TabNavigator({
TabA: {
screen: CoinCap
},
TabB: {
screen: CoinCap
}
}, {
order: ['TabA', 'TabB'],
animationEnabled: true,
})
export const MyScreen = createStackNavigator({
Home: {
screen: CoinCap
},
CoinCapCharts: {
screen: CoinCapCharts
}
},{
initialRouteName: 'Home',
headerMode: 'none'
});
export const Drawer = DrawerNavigator({
Tabs: { screen: Tab },
Stack: { screen: MyScreen },
})
I am importing this in my App.js where I am doing something like this
import React from 'react';
import {
Drawer
}from './Screen.js';
import {
View
} from 'react-native';
export default class App extends React.Component {
render() {
return (
<View>
<Drawer/>
<Tab/>
</View>
);
}
}
Now, This is indeed showing Tab the first time I run my app but after I navigate to different screen and return back, It doesn't appear to be showing that Tab again
[Question:] What could I be doing wrong and How can I fix it?
Try to define one within the other.
Something like:
const Tab = TabNavigator({
TabA: {
screen: Home
},
TabB: {
screen: Home
}
}, {
order: ['TabA', 'TabB'],
animationEnabled: true,
})
export const MyStack = createStackNavigator({
Home: {
screen: Home
},
CoinCapCharts: {
screen: CoinCapCharts
},
Tab: {
screen: Tab
},
},{
initialRouteName: 'Home',
headerMode: 'none'
});
Now, render MyStack (not sure that Screen is the best name :)
export default class App extends React.Component {
render() {
return (
<View>
<MyStack />
</View>
);
}
}

The component for route "Feed" must be a React Component

i am trying to understand reactnavigation and i am setting up a concept app to understand.
What i am struggling at first is, that i get the Error Message "The component for route "SomeRoute" must be a React Component"
I do know, what it means, but i do not understand why this error is thrown.
I have following setup:
App.js:
import React from 'react';
import { Root } from './config/router';
import { SafeArea } from 'react-native';
class App extends Component {
render() {
return <Root />;
}
}
export default App;
router.js( config/router.js )
import React from 'react';
import { DrawerNavigator, TabNavigator, StackNavigator } from 'react-navigation';
import Feed from './../components/Feed';
import Search from './../components/Search';
import Favorites from './../components/Favorites';
import TextList from './../components/ComingSoon';
import Detail from './../components/Detail';
import Downloads from './../components/Downloads';
export const FeedStack = StackNavigator({
Feed: {
screen: Feed,
navigationOptions: {
title: 'Machines'
}
},
List: {
screen: TextList,
navigationOptions: {
title: 'List View'
}
},
Detail: {
screen: Detail,
navigationOptions: {
title: 'Detail'
}
}
});
export const TabStack = TabNavigator({
Dashboard: {
screen: FeedStack,
navigationOptions: {
title: 'Dashboard'
}
},
Search: {
screen: Search,
navigationOptions: {
title: 'Search'
}
},
Favorites: {
screen: Favorites,
navigationOptions: {
title: 'Favorites'
}
}
});
export const DownloadStack = StackNavigator({
Downloads: {
screen: Downloads,
navigationOptions: {
title: 'Downloads'
}
}
});
export const Root = DrawerNavigator({
Feed: {
Screen: TabStack,
navigationOptions: {
title: 'Machines'
}
},
Downloads: {
screen: DownloadStack
}
});
and Feed.js ( components/Feed.js )
import React from 'react';
import { View, Text } from 'react-native';
class Feed extends React.Component {
render() {
return (
<View>
<Text>Hallo Feed Soon</Text>
</View>
);
}
}
export default Feed;
As i can see, Feed is extending React.Component and also exporting a default Classname "Feed".
It seems to be a very Basic Mistake, what am i doing wrong here?
ok i found it.
The route "Feed" in Root has a "Screen" property instead of a "screen" Property.
can be closed by error in front of screen.
if you use react native router flux then this could be problem for using the wrong export syntax.
Usual syntax for export :
export {ComponentName};
or this :
export default ComponentName;
it should be (when using the react-native-router-flux
module.exports = ComponentName;

React navigation Stack Navigator componentdidMount

I'm using react-navigation. Using stack navigator and a drawer nested inside it.How to call componentdidmount and this.props.navgation.navigate in the code below. I have some event which is supposed to navigate user to particular screen rather than following initial route of Drawer.
import React from "react";
import { Platform, Text } from "react-native";
import { Root } from "native-base";
import { StackNavigator, DrawerNavigator} from "react-navigation";
import Register from "./components/Register";
import Home from "./components/home/";
import Dashboard from "./components/Dashboard/";
import SideBar from "./components/sidebar";
import Screen1 from "./components/Screen1/";
import Screen2 from "./components/Screen2/";
import Screen3 from "./components/Screen3/";
const Drawer = DrawerNavigator(
{
Dashboard: { screen: Dashboard },
Screen1: { screen: Screen1 },
Screen2 : { screen: Screen2 },
},
{
navigationOptions: {
gesturesEnabled: false,
},
initialRouteName: "Dashboard",
contentOptions: {
activeTintColor: "#e91e63"
},
drawerPosition: 'right',
contentComponent: props => <SideBar {...props} />
}
);
const AppNavigator = StackNavigator(
{
Home: { screen: Home },
Register: { screen: Register },
Drawer: { screen: Drawer },
Screen3: { screen: Screen3 },
},
{
headerMode: "none",
}
);
//HOW TO WRITE COMPONENTDIDMOUNT HERE AND CALL //THIS.PROPS.NAVIGATION.NAVIGATE
export default () =>
<Root>
<AppNavigator />
</Root>;
You are not creating a component, then you won't be able to "write" ComponentDidMount here.
<Root> have it's own componentDidMount, which runs when you render it.
Be sure to have a good understanding of how React and JSX work together :
https://reactjs.org/docs/rendering-elements.html