Q: ReactNative StackNavigator inside DrawerNavigator - react-native

is there any good no bugs example with StackNavigator inside DrawerNavigator?
As in my example when the drawer is open the top Navigation title is hidden and I can't open the drawer(with slide) when I am inside the NewScreen page.
So I want to open the drawer over the title and from any page.
Thanks
http://image.prntscr.com/image/eb4d869acbcf4d22a08159b072aae930.png
Here is the code
import React, { Component } from 'react';
import {
AppRegistry,
Button,
Platform,
ScrollView,
StyleSheet,
TouchableHighlight,
Text,
} from 'react-native';
import {
DrawerNavigator,StackNavigator
} from 'react-navigation';
import FontAwesome from "react-native-vector-icons/FontAwesome";
class ScreenHome extends Component{
static navigationOptions = {
title: 'ScreenHome',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to Jane's profile"
onPress={() => navigate('New', { name: 'Jane' })}
/>
);
}
}
class NewScreen extends Component{
static navigationOptions = {
title: 'New screen',
};
render() {
const { navigate } = this.props.navigation;
return (
<Text>Some new screen</Text>
);
}
}
class ScreenRegister extends Component{
static navigationOptions = {
title: 'ScreenRegister',
};
render(){
return <Text>ScreenRegister</Text>
}
}
const MainScreenNavigator = DrawerNavigator({
Recent: {
screen: ScreenHome
},
All: {
screen: ScreenRegister
},
});
export default SimpleApp = StackNavigator({
Home: {
screen: MainScreenNavigator
},
Chat: {
screen: ScreenHome
},
New: {
screen: NewScreen
}
});
AppRegistry.registerComponent('naviTest', () => SimpleApp);

If I got your questions correctly, you want:
1) To have access to the drawer from any page
2) Your drawer to cover the title bar when open.
To achieve Number 1
There are two ways you can do it and they are:
a) Add a button/Icon that triggers the drawer on click. When you use this solution, you will still not have the slide from left functionality as this is controlled explicitly by the DrawerNavigator
b) Add NewScreen to your Drawer since you want to have access to the entire drawer when you are within the screen
To achieve Number 2
This is a very common issue when nesting DrawerNavigator within StackNavigator. To resolve this, modify StackNavigator thus
export default SimpleApp = StackNavigator({
Home: {
screen: MainScreenNavigator
},
Chat: {
screen: ScreenHome
},
New: {
screen: NewScreen
}
}, {
navigationOptions: { header: false }
});

Related

React-native with react-navigation: header not showing in screen

I do have a simple React-native app, using react-navigation for navigation. My issue is that for one of the screens the header and title is not showing, even though it is set in navigationOptions:
main.js:
import React from "react";
import { View, Text } from "react-native";
import {
createDrawerNavigator,
createAppContainer,
createStackNavigator
} from "react-navigation";
import ArticleList from "./screens/ArticleList";
import ArticleList2 from "./screens/ArticeList2";
import ArticleWebView from "./screens/ArticleWebView";
// create the Navigator to be used
const Stack = createStackNavigator({
ArticleList: { screen: ArticleList },
ArticleWebView: { screen: ArticleWebView }
});
const Drawer = createDrawerNavigator(
{
Stack: { screen: Stack },
ArticleList2: { screen: ArticleList2 }
},
{
initialRouteName: "Stack"
}
);
// The container for the navigator
const AppContainer = createAppContainer(Drawer);
class App extends React.Component {
render() {
return <AppContainer />;
}
}
export default App;
The ArticleList2 is a very simple component:
import React from "react";
import { View, Text } from "react-native";
import ArticleListComponent from "../components/ArticleListComponent";
class ArticleList2 extends React.Component {
static navigationOptions = {
title: 'Link2'
};
render() {
return (
<View>
<Text>LIst2</Text>
</View>
);
}
}
export default ArticleList2;
However, the title and header are not rendered in the app. Could anybody help please?
DrawerNavigator does not include a header. In order to create a header inside of ArticleList2 you will have to create a new StackNavigator for the component.
You have to think about and plan out the navigation flow of your app.
The Drawer section of the React Navigation documentation is a little lacking, but you can use the same principle as described in the Tab section
A stack navigator for each tab
const ArticleList2Stack = createStackNavigator({
ArticleList2: { screen: ArticleList2 }
});
const Drawer = createDrawerNavigator(
{
Stack: { screen: Stack },
ArticleList2: { screen: ArticleList2Stack }
},
{
initialRouteName: "Stack"
}
);

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;

How to send parameters from screen to stack navigator?

I am a newbie to react native.
I am using a stack navigator inside a tab navigator; I have to navigate multiple screens inside each tab. i am able to send parameters from my default class HomePage to my nested classes in my tab and stack navigators.
export const MyApp = TabNavigator({
Asset: {
screen: AssetScreen,
},
Sensors: {
screen: sensorsStack,
},
Settings: {
screen: settingStack
},
}
export const sensorsStack = StackNavigator({
sensors : { screen: SensorScreen },
sensorDetails : { screen: SensorDetails }
});
export const settingStack = StackNavigator({
settings: { screen: SettingsScreen },
about : { screen: About },
environment : { screen: Environment }
});
export default class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
assetID:'xyz',
authToken:'xyzz'
}
}
static navigationOptions = {
header: null
};
render() {
const screenProps = {
asset: {
assetID: this.state.assetID,
authToken : this.state.authToken,
},
}
return (
<MyApp screenProps={screenProps} />
);
}
}
Now, i want to send a parameter from 'SensorScreen' to 'SensorDetails'. I have tried sending parameters using
NavigationActions.navigate({ routeName: 'sensorDetails' ,params: { sensorType:'Fuel',}});
from 'SensorScreen' class. But was not able to get the parameter in 'SensorDetails' class. How can i pass this params?
A little late answer but might help others that ends up here.
Instead of using NavigationActions you could try navigation from sensorScreen to sensorDetails with navigate and passing some extra variables.
this.props.navigation.navigate('SensorDetails',{sensorType:'Fuel'})
The passed object can then be read in the second screen by
this.props.navigation.state.params.sensorType
A minimal example of the case can be seen in these lines. Observe that this is a stupid on icon tab bar. But it is kept that way since the question was about a tab bar with stacks on each tab. And new tabs are easily added.
import React,{Component} from 'react'
import { Text, View, Footer,Button } from 'react-native'
import {StackNavigator,TabNavigator} from 'react-navigation'
export class SensorScreen extends React.Component {
render() {
return (<Button
onPress={() => this.props.navigation.navigate('SensorDetails',{sensorType:'Fuel'})}
title="Go to Sensor Details"
/>)}}
export class SensorDetails extends React.Component {
render() {
return (<View>
<Text>{this.props.navigation.state.params.sensorType}</Text>
</View>);}
}
const sensorsStack = StackNavigator({
sensors : { screen: SensorScreen },
SensorDetails : { screen: SensorDetails }
});
const MyApp = TabNavigator({
Sensors: {
screen: sensorsStack,
},
});
export default class Nested extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<MyApp/>
);
}
}
Hope this helps.

How to hide the tabBar in the child screen of a StackNavigator

I declare two screens A and B in a StackNavigator. The StackNavigator is nested in a tabNavigator. The bar is visible for the both screens. And i want to show it just in the screen A. I set the tabBarVisible to false in the screen B but no effects.
import React,{Component} from 'react';
import {Text} from 'react-native';
import {StackNavigator, TabNavigator} from 'react-navigation';
class ScreenA extends Component {
static navigationOptions = {
title: 'A'
}
render(){
<Text>ScreenA</Text>
}
}
class ScreenB extends Component {
static navigationOptions = {
title: 'B'
}
render(){
<Text>ScreenB</Text>
}
}
const HomeScreen = new StackNavigator({
A : {screen : ScreenA},
B : {Screen : ScreenB}
});
const TabBar = new TabNavigator({
Main : {screen : HomeScreen}
});
export default TabBar;
If you don't want to see the TabBar with screen B, you should not nest screen B inside a TabNavigator, you need to redesign you navigator to move the screen B out of the TabNavigator.
AppScreen.js
import React, {Component} from "react";
import {Button, Text, View} from "react-native";
import {NavigationActions, StackNavigator, TabNavigator} from "react-navigation";
//reference to the root App navigator
let appNavRef;
class ScreenA extends Component {
static navigationOptions = {
title: 'A'
};
_handlerPress = () => {
//handle navigation
const navigateAction = NavigationActions.navigate({
type: 'Navigation/NAVIGATE',
routeName: 'bNav',
params: {},
});
appNavRef.dispatch(navigateAction)
};
render() {
return (
<View>
<Text>ScreenA</Text>
<Button title="GoToB" onPress={this._handlerPress}/>
</View>
)
}
}
class ScreenB extends Component {
static navigationOptions = {
title: 'B'
};
render() {
return <Text>ScreenB</Text>
}
}
const HomeScreen = new StackNavigator({
A: {screen: ScreenA}
//move screen B outside
});
const TabBar = new TabNavigator({
Main: {screen: HomeScreen}
});
class TabScreen extends Component {
//hide the StackNavigator header bar
static navigationOptions = {
header: null,
};
render() {
return (
<TabBar/>
);
}
}
const AppNav = new StackNavigator({
tabNav: {screen: TabScreen},
bNav: {screen: ScreenB}
});
class App extends Component {
render() {
return (
//get the reference to the root navigator
<AppNav ref={navigatorRef => {
appNavRef = navigatorRef
}}/>
);
}
}
export default App;
index.android.js
import AppScreen from './src/test/AppScreen'
export default class myapp extends Component {
render() {
return (<AppScreen/>);
}
}
//the rest code...
It's quite easy actually, just set tabBarVisible to false in navigationOptions