How to get bottomTab press action with wix react-native-navigation? - react-native

I have set up navigation with Bottom tabs in react-native-navigation, this is working fine
bottomTabs: {
id: 'BOTTOM_TABS_LAYOUT',
children: [
{
stack: {
id: 'HOME_TAB',
children: [
{
component: {
id: 'HOME_SCREEN'
name: 'HomeScreen'
}
}
],
options: {
bottomTab: {
icon: require('./home.png')
}
}
}
},
{
stack: {
id: 'PROFILE_TAB',
children: [
{
component: {
id: 'PROFILE_SCREEN',
name: 'ProfileScreen'
}
}
],
options: {
bottomTab: {
icon: require('./profile.png')
}
}
}
}
]
}
But I want to add some other code when I switch from a tab to another, how could this be done?

You can listen to tab selection events by registering a Navigation events listener. The tabSelected event is emitted when the selected tab has changed.
Navigation.events().registerBottomTabSelectedListener((selectedTabIndex, unselectedTabIndex) => {
});
If you'd like to handle the tab selection yourself, set the selectTabOnPress: false option on the bottomTab you'd like to handle selection for, and register a tabPressed listener to handle the tab press event. This event is emitted when a tab is pressed by the user.
options: {
bottomTab: {
icon: require('./home.png'),
selectTabOnPress: false
}
}
Navigation.events().registerBottomPressedListener((tabIndex) => {
});

Related

Wix RNN v3 Navigation.pop() callback?

I'm using Wix's react-native-navigation V3. I'd need to know if there's a way to call a function whenever Navigation.pop() is finished executing.
My specific case scenario is as follows.
I have 3 stack tab buttons, where I can push a new screen and pop back.
All works fine, except for the case that, from that pushed screen, I'd need to go to a different tab. If I mergeOptions directly to change currentTabIndex, the bottomTabs will disappear. Found out that I have to first, pop() and then mergeOptions.
Is there a way to accomplish this? When I run both in the same function, only pop() is triggered, I need to add some sync to this.
This is my current stack structure:
const startTabs = () => {
Navigation.setRoot({
root: {
bottomTabs: {
animate: true,
visible: false,
drawBehind: true,
elevation: 8,
waitForRender: true,
children: [
{
stack: {
id: 'MainTabStack',
children: [
{
component: {
id: 'MainTab',
name: 'app.MainTab'
}
}
],
options: {
bottomTab: {
text: i18n.t('home'),
icon: iconsMap['home-light'],
selectedIcon: iconsMap['home-solid'],
...navigatorStyle
}
}
}
},
{
stack: {
id: 'MyProfileTabStack',
children: [
{
component: {
id: 'MyProfileTab',
name: 'app.MyProfileTab'
}
}
],
options: {
bottomTab: {
text: i18n.t('myProfile'),
icon: iconsMap['user-light'],
selectedIcon: iconsMap['user-solid'],
...navigatorStyle
}
}
}
},
{
stack: {
id: 'MessageTabStack',
children: [
{
component: {
id: 'MessageScreen',
name: 'app.MessageScreen'
}
}
],
options: {
bottomTab: {
text: i18n.t('messages'),
icon: iconsMap['message-light'],
selectedIcon: iconsMap['message-solid'],
badgeColor: 'red',
...navigatorStyle
}
}
}
}
]
}
}
});
}
So I start from MainTab, then I push a new screen from this MainTab. Let's name it SingleViewScreen. When I'm done doing some stuff in SingleViewScreen, by an onPress function I need to pop() this current screen and go directly to MessageScreen.
Any ideas? Am I doing something wrong? Thanks.
You can use registerCommandCompletedListener
Invoked when a command (i.e push, pop, showModal etc) finishes executing in native. If the command contains animations, for example pushed screen animation, the listener is invoked after the animation ends.
Try this
// Subscribe
const commandCompletedListener = Navigation.events().registerCommandCompletedListener(({ commandId, completionTime, params }) => {
});
...
// Unsubscribe
commandCompletedListener.remove();

react-native-navigation side menu

I'm trying to use the library react-native-navigation v2, i need some help I'm stuck with the side menu, i can't make it work...
I initialized my layout like this :
Navigation.events().registerAppLaunchedListener(() => {
Navigation.setRoot({
root: {
sideMenu: {
id: "sideMenu",
left: {
component: {
id: "Drawer",
name: "navigation.Drawer"
}
},
center: {
stack: {
id: "AppRoot",
children: [
{
component: {
id: "App",
name: "navigation.AppScreen"
}
}
]
}
}
}
}
});
});
With Components registered before, and in the Drawer component I want that when the user click on the item, it will trigger the goToScreen2(),
I tried :
Navigation.setStackRoot(this.props.componentId, {...}
Navigation.mergeOptions(this.props.componentId, {...}
Navigation.push(this.props.componentId, {...}
But, none works... someone can explain how can i make it works ?
Thanks.
You should add all the components that you want to navigate to from side menu in the center of your root stack as the following:
center: {
stack: {
id: "AppRoot",
children: [{
component: {
id: "anyID",
name: "Screen2"
}
}]
}
}

Can we use two layouts together in wix RNN v2?

I want side menu in a particular screen in stack navigation.
How can i navigation.push to a screen in stack navigation having a side menu in react native navigation v2. As Navigation.push only takes component object.
Navigation.setRoot({
root: {
stack: {
id: 'App',
children: [
{
component: {
name: 'FormList',
options: {
topBar: {
title: {
text: 'Forms'
}
}
}
}
}
],
}
}
});
I want to push to a screen in CreateForm which would have a sidemenu
const sidemenu = {
sideMenu: {
center: {
component: {
name: 'CreateForm',
options: {
topBar: {
title: {
text: 'Create Form'
},
},
}
},
},
right: {
component: {
name: 'CreateField',
passProps: {
text: ''
},
},
},
}
};

ReactNative: Using React Native Navigation how can I move to next screen

I have root screen that contains 4 bottoms tabs implemented using react-native-navigation, for one of my bottomtab having sub tabs(topTabs) so now how can I navigate to next screen from the current screen.(note: the next screen is not a registered screen in root)
please anyone help me
here is my root navigation
export const startNavigation = () => {
Navigation.setRoot({
root: {
sideMenu: {
left: {
component: {
name: screenName.DRAWER
}
},
center: {
bottomTabs: {
children: [{
stack: {
children: [{
component: {
name: screenName.Sample1
}
}],
options: {
bottomTab: {
text: 'Sample1',
}
}
}
}, {
stack: {
children: [{
component: {
name: screenName.HOME
}
}],
options: {
bottomTab: {
text: 'Home',
selectedTextColor: 'red'
}
}
}
}],
options: {
bottomTabs: {
currentTabIndex: 1
}
}
}
}
}
}
})
}
from this root, how I will navigate to sub tabs or sunscreens
Have you tried anything? can you post some code?
if you are getting started, here is the official documentation from React Native
https://wix.github.io/react-native-navigation/#/docs/Usage

wix react native navigation v2 | how to push new screen to current screen from side drawer component

I have the next layout:
Navigation.setRoot( {
root: {
sideMenu: {
right: {
component: {
id: 'sideDrawer',
name: DRAWER,
}
},
center: {
bottomTabs: {
id: 'bottomTabs',
children: [
{
stack: {
children: [
{
component: {
id: 'searchTab',
name: SEARCH_TAB,
options: {
bottomTab: {
text: 'Search',
icon: iconsMap[ 'search' ],
testID: 'searchTab',
},
topBar,
}
}
}
]
}
},
{
stack: {
children: [
{
component: {
id: 'secondTab',
name: SECOND_TAB,
options: {
bottomTab: {
text: 'Second Tab',
icon: iconsMap[ 'random' ],
testID: 'secondTab',
},
topBar,
}
}
}
]
}
},
]
}
}
}
}
} )
The drawer is open when a hamburger button in the topBar on any tab is tapped. In the side drawer I have a few menu items. When I tap an item I want to push a new screen to currently active tab ( searchTab or secondTab ). Please note I'm pushing from the drawer component. The challenge is how to know the id of the currently active item to push to or is there any other way to do that?
Ok, figured out. Hopefully this will help someone else also struggling with this. In my drawer component I have a global listener:
constructor( props: Props ) {
super( props )
Navigation.events().registerComponentDidAppearListener( ( { componentId } ) => {
// only spy on tabs we don't need other screens
if (componentId === 'searchScreen' || componentId === 'secondScreen') {
this.setState({
activeComponentId: componentId
})
}
}
Then when I need to open a screen I already have the active component id and can safely push new screen onto it.
openMenuItem( screenName ) {
// close drawer
Navigation.mergeOptions( 'sideDrawer', {
sideMenu: {
right: {
visible: false
}
}
} )
// open menu item
Navigation.push( this.state.activeComponentId, {
component: { name: screenName }
}
}
I used a similar solution by listening to the BottomTabSelected event inside of a react function component.
const [activeTabIndex, setActiveTab] = useState(2 /** My default tab is 2**/ );
useLayoutEffect(() => {
const sub = Navigation.events().registerBottomTabSelectedListener(({ selectedTabIndex, unselectedTabIndex }) => {
setActiveTab(selectedTabIndex);
})
return () => sub.remove();
}, [])
And made each of my bottom stacks have an id that correlated to the tab index.
center: {
bottomTabs: {
children: [{
stack: {
id: "BottomTabs_0",
children: [{
component: {/** Component Info Here **/}
}]
}
},
{
stack: {
id: "BottomTabs_1",
children: [{
component: {/** Component Info Here **/}
}]
}
},
{
stack: {
id: "BottomTabs_2",
children: [{
component: {/** Component Info Here **/}
}]
}
}]
}
}