How can I change my view from Tab to Screen on Navigation.push with react-native-navigation - react-native

I have a screen that has three bottom tabs, in one of the tab screens I want to move to a completely new page using Navigation.push but it's not working. Please anyone who can help out with switching from tab based view to push screen(that has no tabs. stack I guess)
below is my navigator.js file that contains the initial logic for switching to tabs view on login
Navigation.registerComponentWithRedux('HomeScreen', ()=> Home, Provider, store)
Navigation.registerComponentWithRedux('FindPlace', ()=> FindPlace, Provider, store)
Navigation.registerComponentWithRedux('SharePlace', ()=> SharePlace, Provider, store)
Navigation.registerComponent('PlaceDetailScreen', ()=> PlaceDetailScreen);
export const startNavigation = () => {
Promise.all([
Icon.getImageSource('ios-search', 30),
Icon.getImageSource('md-share', 30, 'blue'),
Icon.getImageSource('ios-home', 30, 'darkblue'),
]).then(icons => {
Navigation.setRoot({
root: {
bottomTabs: {
children: [
{
component: {
name: 'HomeScreen',
options: {
bottomTab: {
text: 'Home',
fontSize: 10,
icon: icons[2]
}
}
}
},
{
component: {
name: 'FindPlace',
options: {
bottomTab: {
text: 'Find a Place',
fontSize: 10,
icon: icons[0]
}
},
passProps: {
data: 'Data'
}
}
},
{
component: {
name: 'SharePlace',
options: {
bottomTab: {
text: 'Share Place',
fontSize: 10,
icon: icons[1]
}
}
}
}
]
}
}
})
})
}
below is my dummy login page that I use to call the tabs logic
import {startNavigation} from '../../../navigation';
const AuthScreen = props=> {
const navigateTabs = () => {
startNavigation()
}
return (
<View style={styles.authScreen}>
<TextInput placeholder='Username'/>
<Button title='Log me in' color='green' onPress={navigateTabs}/>
</View>
)
}
below is the code I am trying to use to push a new screen which is not working
const handleItemSelect = key => {
const selPlaces = places.places.find(item => item.key === key);
Navigation.push(props.componentId, {
component: {
name: 'PlaceDetailScreen',
options: {
topBar: {
visible: true,
title: {
text: selPlaces.name
}
}
},
passProps: {
selectedPlace: selPlaces
}
}
})
}

Solved it! the issue was with how I was setting the root in my main navigation.js file. I wasn't doing it properly.
here is the updated root as instructed here https://wix.github.io/react-native-navigation/#/docs/top-level-api?id=setrootlayout
bottomTabs: {
children: [
{
stack: {
children: [
{
component: {
name: 'HomeScreen',
options: {
bottomTab: {
text: 'Home',
fontSize: 10,
icon: icons[2]
},
topBar: {
visible: true,
leftButtons: [
{
id: 'sideMenu',
icon: icons[3]
}
],
noBorder: true
}
}
}
}
]
}
},
{
stack: {
children: [
{
component: {
name: 'FindPlace',
options: {
bottomTab: {
text: 'Find a Place',
fontSize: 10,
icon: icons[0]
},
topBar: {
leftButtons: [
{
id: 'sideMenu',
icon: icons[3]
}
],
noBorder: true
}
},
passProps: {
data: 'Data'
}
}
},
]
}
},
{
stack: {
children: [
{
component: {
name: 'SharePlace',
options: {
bottomTab: {
text: 'Share Place',
fontSize: 10,
icon: icons[1]
},
topBar: {
leftButtons: [
{
id: 'sideMenu',
icon: icons[3]
}
],
noBorder: true
}
},
passProps: {
data: 'data'
}
}
}
]
}
}
]
}

Related

React-Native-Navigation [V3], back to previous page

Please help, i will explain first by showing the code :
home.js
onHelpPagePress() {
Promise.all([
AntDesign.getImageSource('arrowleft', 25)
]).then((sources) => {
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
name: 'projectName.HelpPage',
options: {
topBar: {
title: {
text: 'Screen Name 1',
},
drawBehind: false,
leftButtons: [
{
id: 'backButton',
enabled: true,
showAsAction: 'ifRoom',
component: {
name: 'projectName.Home',
passProps: {
color: 'white',
// pass event here
}
},
icon: sources[0],
color: 'white',
},
],
}
}
},
}]
}
}
});
});
}
it will looks like this :
------------------------------------
<- Screen Name 1
------------------------------------
how can i access the back button in the new screen?
and could someone help me how can i go to the previous screen?
thanks
it fixed when using navigation.showmodal

React Native Navigation - bottom tabs and drawer

I'm trying to add bottom tab bar in my jhipster ignite application, which uses react-native-navigation v2.
Screens are registered like:
Navigation.registerComponentWithRedux(LAUNCH_SCREEN, () => LaunchScreen, Provider, store)
Where e.g.:
export const LAUNCH_SCREEN = 'nav.LaunchScreen'
And here is the complete navigation:
export const topBar = {
title: {
text: 'MDNGHT',
color: Colors.snow
},
leftButtons: [
{
id: 'menuButton',
icon: Images.menuIcon,
testID: 'menuButton',
color: Colors.snow
}
]
}
export const launchScreenComponent = {
component: {
id: 'id.launch',
name: LAUNCH_SCREEN,
options: {
topBar: topBar,
bottomTab: {
fontSize: 12,
text: 'HOME'
}
}
}}
export const eventsScreenComponent = {
component: {
id: 'id.events',
name: EVENTS_SCREEN,
options: {
topBar: topBar,
bottomTab: {
fontSize: 12,
text: 'EVENTS'
}
}
}
}
export const bottomTabs = {
id: 'bottomTabs',
children: [
{
stack: {
children: [
launchScreenComponent
]
}
},
{
stack: {
children: [
eventsScreenComponent
]
}
}
],
options: {
bottomTabs: {
activeTintColor: 'red',
inactiveTintColor: 'grey',
backgroundColor: '#121212',
borderTopWidth: 0,
shadowOffset: {width: 5, height: 3},
shadowColor: 'black',
shadowOpacity: 0.5,
elevation: 5
}
}
}
export const appStack = {
root: {
sideMenu: {
left: {
component: {
name: DRAWER_CONTENT
}
},
center: {
bottomTabs: bottomTabs
}
}
}
}
Navigation.events().registerAppLaunchedListener(() => {
Navigation.setDefaultOptions({
topBar: {
topBar: {
title: {
color: Colors.snow
}
},
backButton: {
showTitle: false,
testID: 'backButton',
icon: Images.chevronLeftIcon,
color: Colors.snow,
iconColor: Colors.snow
},
background: {
color: Colors.background
}
},
sideMenu: {
left: {
enabled: false
}
}
})
Navigation.setRoot(appStack)
// handle app state and deep links
AppState.addEventListener('change', handleAppStateChange)
Linking.addEventListener('url', handleOpenURL)
})
I don't get any error message, my application just stops after start.
When I put:
stack: {
id: 'center',
children: [launchScreenComponent]
}
Instead of bottomTabs: bottomTabs in appStack, the application works (but without bottom tab bar)
Following the Layout docs from react-native-navigation, you can replace the appStack with a bottomTabs implementation instead of a drawer like below (only one tab configured as example, add another object in root.bottomTabs.children to add another tab).
export const appStack = {
root: {
bottomTabs: {
children: [
{
stack: {
id: 'firstTabStack',
children: [
{
component: {
name: LAUNCH_SCREEN,
options: {
topBar: {
title: {
text: 'Welcome!',
color: Colors.snow
}
}
}
}
}
],
options: {
bottomTab: {
iconColor: 'gray',
textColor: 'gray',
selectedIconColor: 'black',
selectedTextColor: 'black',
text: 'Launch Screen',
testID: 'LAUNCH_SCREEN',
icon: Images.menuIcon
}
}
}
}
]
}
}
}
It actually turns out that it is required to set an icon for each bottom tab, otherwise the app crashes:
bottomTab: {
fontSize: 12,
text: 'HOME'
icon: require('../shared/images/logo.png')
}
This resolves the issue.

WIX React Native Navigation: Show side drawer in tab based app

I am using React Native Navigation v2 from WIX in my RN project. For Dashboard(goToDahboard) stack I need to show hamburger icon on the left on on click show side drawer. How can this be implemented?
Since upgrading from v1, side menu options has changed and the docs aren't clear enough.
export const goToDashboard = () =>
Promise.all([
Icon.getImageSource('home', 22, '#272727'),
Icon.getImageSource('th-list', 22, '#272727'),
]).then(sources => {
Navigation.setRoot({
root: {
bottomTabs: {
children: [
{
stack: {
children: [
{
component: {
name: 'Dashboard',
},
},
],
options: {
bottomTab: {
icon: sources[0],
text: 'Dashboard',
},
},
},
},
{
stack: {
children: [
{
component: {
name: 'Settings',
},
},
],
options: {
bottomTab: {
icon: sources[1],
text: 'Settings',
},
},
},
},
],
id: 'bottomTabs',
},
},
});
});
export const goToAuth = () =>
Navigation.setRoot({
root: {
stack: {
id: 'Login',
children: [
{
component: {
name: 'Login',
},
},
],
},
},
});
I'am using like this, thats my code;
Navigation.setRoot({
root:{
sideMenu:{
left:{
component:{
name:'app.Main.SideDrawer'
}
},
center:{
bottomTabs:{
id: 'MainAppBottomTab',
children:[
{
stack:{
children:[
{
component:{
name: 'app.Main.Bottom_1',
options:{
bottomTab:{
text: "Bottom 1",
icon: require('./../../assets/images/Bottom_1.png'),
}
},
}
}
],
options: {
bottomTab: {
text: 'Bottom 1',
},
bottomTabs:{
backgroundColor: ColorTable.orange,
animate:false,
},
topBar:{
title:{
text: 'Bottom 1',
},
leftButtons:[
{
id: 'btn_toggle_drawer',
name: 'BTN_TOGGLE_DRAWER',
icon: require('./../../assets/images/hamburger_icon.png'),
}
],
}
}
}
}
]
}
}
}
}
});
Now we need to use wix's life cycle.
If you want to close it in SideDrawer, you should use the following code;
Navigation.mergeOptions(this.props.componentId, {
sideMenu: {
left: {
visible: false
}
}
});
this.props.componentId equal to app.Main.SideDrawer. Because of we are in app.Main.SideDrawer component.
If you want to open with hamburger icon, Go to whatever page you want to use for bottomTab, in our example I said Bottom_1.
Don't forget to type Navigation.events().bindComponent(this) into the constructor method. This allows you to linking with native.
Only the following command will work;
navigationButtonPressed({buttonId}) {
if (buttonId === "btn_toggle_drawer") {
Navigation.mergeOptions(this.props.componentId, {
sideMenu: {
left: {
visible: true
}
}
});
}
}
The code above works but is problematic. You're going to tell me that I'm going to have to press twice to turn it off =)
The solution is to use redux. Or mobx whichever you prefer.
To solve this problem, I used redux and redux-thunk.
Wix's is life cycle, please explore it: https://wix.github.io/react-native-navigation/#/docs/Usage?id=screen-lifecycle
With redux solution
Real function is;
navigationButtonPressed({buttonId}) {
if (buttonId === "btn_toggle_drawer") {
this.props.toggleDrawer(this.props.isSideDrawerVisible);
Navigation.mergeOptions(this.props.componentId, {
sideMenu: {
left: {
visible: this.props.isSideDrawerVisible
}
}
});
}
}
toggle_drawer action
export const toggleDrawer = (visible) => {
return (dispatch) => {
(visible) ? visible = true : visible = false;
dispatch({
type: TOGGLE_DRAWER,
payload: visible
});
}
};
toggle_drawer reducer
const INITIAL_STATE = {
isSideDrawerVisible: true
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case TOGGLE_DRAWER:
return {...state, isSideDrawerVisible: action.payload};
default:
return state;
}
}
Sample connect function;
import {connect} from "react-redux";
// actions
import {toggleDrawer} from "../../../actions/toggle_drawer";
const mapStateToProps = state => {
return {
isSideDrawerVisible: state.toggleDrawer.isSideDrawerVisible,
}
};
export default connect(mapStateToProps, {toggleDrawer})(Bottom_1_Screen);
Don't forget to connect wix with Redux. https://wix.github.io/react-native-navigation/#/docs/third-party?id=redux
I hope I can help you, I saw it a little late.
Have a nice day..
You can use
Navigation.mergeOptions()
like this to fire and open the drawer:
navigationButtonPressed = ({ buttonId }) => {
const { componentId } = this.props;
if (buttonId === 'sideMenu') {
Navigation.mergeOptions(componentId, {
sideMenu: {
left: {
visible: true,
},
},
});
}
}

React native navigation wix push screen problem

i have a created a tab based navigation with WIX and each time i am trying to push a screen from any screen of the tabs it doesn't do anything but , when i try to push from the first tab it works but any other tab i can't push from it
Promise.all(iconTabs).then(sources => { // after the promises end
Navigation.setRoot({
root: {
bottomTabs: {
children: [{
stack: {
children: [{
component: { // 1
name: screenNames['listInvoice'].name,
}
}],
options: {
bottomTab: {
text: screenNames['listInvoice'].title,
icon: sources[0],
selectedIconColor: DEFAULT_COLOR,
},
topBar: getTopBar()
}
}
},
{
component: { // 2
name: screenNames['listReceipt'].name,
options: {
bottomTab: {
text: screenNames['listReceipt'].title,
icon: sources[1],
selectedIconColor: DEFAULT_COLOR,
},
topBar: getTopBar()
}
} ,
},
{
component: { // 2
name: screenNames['listCustomer'].name,
options: {
bottomTab: {
text: screenNames['listCustomer'].title,
icon: sources[2],
selectedIconColor: DEFAULT_COLOR,
},
topBar: getTopBar()
}
} ,
},
{
component: { // 2
name: screenNames['listInvoiceItem'].name,
options: {
bottomTab: {
text: screenNames['listInvoiceItem'].title,
icon: sources[3],
selectedIconColor: DEFAULT_COLOR,
},
topBar: getTopBar()
}
} ,
},
{
component: { // 2
name: screenNames['listSupplier'].name,
options: {
bottomTab: {
text: screenNames['listSupplier'].title,
icon: sources[4],
selectedIconColor: DEFAULT_COLOR,
},
topBar: getTopBar()
}
} ,
},
]
}
}
});
});
-->
Navigation.push(currentScreen, {
component: {
name: screenName,
options: {
topBar: getTopBar(),
bottomTabs: {
visible: false,
drawBehind: true
}
}
}
});
-->
Environment
React Native Navigation version: the latest one
react-native-cli: 2.0.1
react-native: 0.58.4
Platform(s)Android
I had the same issue.
You have to initiate the other tabs a stack layout as well. Like:
bottomTabs: {
children: [
........
{
stack: {
children: [
{
component: { screenNames['listReceipt'].name }
}
]
}
},
{
stack: {
children: [
{
component: { screenNames['listCustomer'].name }
}
]
}
}
]
}
See also here: https://github.com/wix/react-native-navigation/issues/4786#issuecomment-467648825

React Native Navigation v2 sideMenu not able to navigate to screen

I'm trying to call Navigate.push from sideMenu but nothing happens.
Navigation.setRoot({
root: {
sideMenu: {
left: {
component: {
name: 'app.SideMenu',
},
children: [
{
stack: {
children: [
{
component: {
name: TERMS_SCREEN.id,
}
},
]
}
}
]
},
center: {
bottomTabs: {
id: 'BottomTabsId',
options: {
topbar: {
visible: true,
}
},
children: [
{
stack: {
id: 'Tabs',
children: [
{
..and I'm trying to push a screen in sideMenu like this
console.log(this.props.componentId);
Navigation.push(this.props.componentId, {
component: {
name: 'app.Terms',
}
})
I am getting the log but nothing happens. I'm positive that I need to do something with my layout but I don't see an example or explanation in docs.
There's something wrong with how you structure the components in the menu. The issue is that you must have a stack to be able to push other screens, and from what it looks - this is not the case for your side menu screen.
This is how you would set a left sideMenu component which is a stack; once you do that, you'll be able to push screens exactly as you did with Navigation.push(this.props.componentId...:
left: {
stack: {
children: [
{
component: {
name: 'app.SideMenu',
}
}
]
}
}
What I was doing wrong is actually because I'm passing the sidemenu componentId when in fact I need to pass the id of the current tab. Something like this.
Navigation.push(`Tab${this.props.activeTabIndex + 1}`,{
component: {
name: Screens.ACCOUNTS,
}
}
)
also sidemenu layout is this
root: {
sideMenu: {
id: 'SideMenu',
left: {
component: {
id: 'SideMenu.left',
name: Screens.SIDEMENU,
}
},
while having children and stack in sidemenu object might be one solution. but you could do this as well. Consider following
Navigation.setRoot({
root: {
sideMenu: {
left: {
id: "AppSideMenu",
component: {
id: "HomeScreenDrawer",
name: "YO.HomeScreen.Drawer",
},
},
center: {
stack: {
id: "AppHomeStack",
children: [
{
component: {
id: "AppHomeScreen",
name: "YO.HomeScreen",
options: {
topBar: {
visible: false,
drawBehind: true,
height: 0,
},
statusBar: {
style: "light",
},
},
},
},
],
},
},
},
},
});
This way when you are going to push just call the ID of your main stack which lies under center{stack:{}} with ID of AppHomeStack
Now anywhere in the app, this will just do the trick
Navigation.push("AppHomeStack", {
component: {
name: "YO.UserScreen",
},
});