Get name of previous route to go back to - react-native

I have nested stacks in my app. With two different headers.
I have a reset but this just send the user back to the home screen regardless. How can I get the previous route?
resetForm() {
const { dispatch } = this.props.navigation;
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: "Drawer" })]
});
this.props.navigation.dispatch(resetAction);
}
App Navigator:
const config = {
contentOptions: {
activeTintColor: "#e91e63",
inactiveTintColor: "#ffffff",
itemStyle: {
flexDirection: "row-reverse"
}
},
drawerWidth: 300,
overlayColor: "#003366",
drawerPosition: "right",
drawerBackgroundColor: "#009999",
transparentCard: true,
cardStyle: {
backgroundColor: "transparent",
opacity: 1
},
transitionConfig: () => ({
containerStyle: {
backgroundColor: "transparent"
}
})
};
const withHeader = (
screen: Function,
routeName: string,
Header
): StackNavigator =>
createStackNavigator(
{
[routeName]: {
screen,
navigationOptions: ({ routeName, props }) => ({
header: props => <Header {...props} />
})
}
},
{
initialRoute: "Home",
transparentCard: true,
cardStyle: {
backgroundColor: "transparent",
opacity: 1
},
transitionConfig: () => ({
containerStyle: {
backgroundColor: "transparent"
}
})
}
);
const routes = {
VideoEpisodes: {
screen: withHeader(VideoEpisodesScreen, "Video Episodes", DrawerHeader)
},
TestYourself: {
screen: withHeader(TestYourselfScreen, "Test Yourself", DrawerHeader)
},
MyResults: {
screen: withHeader(MyResultsScreen, "My Results", DrawerHeader)
},
BookmarkedVideos: {
screen: withHeader(
BookmarkedVideosScreen,
"Bookmarked Videos",
DrawerHeader
)
},
About: {
screen: withHeader(AboutScreen, "About", DrawerHeader)
}
};
const NestedDrawer = createDrawerNavigator(routes, config);
const MainStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
},
Drawer: {
screen: NestedDrawer,
navigationOptions: ({ props }) => ({
header: () => null
})
},
VideoPlayer: {
screen: VideoPlayerScreen,
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
}
},
{
initialRoute: "Home",
transparentCard: true,
cardStyle: {
backgroundColor: "transparent",
opacity: 1
},
transitionConfig: () => ({
containerStyle: {
backgroundColor: "transparent"
}
})
}
);

Related

How to call a alert from bottom tab navigator in react navigation v4

For calling a stackNavigator we use props.navigation.navigate('home').
But how to call for alert when i clicked on a bottom tab navigation icon.
You can use tabBarOnPress in navigationOptions as below
CreatePostt: {
screen: createStackNavigator(
{
CreatePost: {
screen: CreatePost,
navigationOptions: {
// header: null
}
},
PostExpanded: {
screen: PostExpanded,
navigationOptions: {
title: "Upload Post",
headerStyle: {
elevation: 1
},
}
},
},
{
defaultNavigationOptions: {
headerTitleStyle: {
fontWeight: "bold"
}
}
}
),
navigationOptions: {
tabBarOptions: {
showIcon: true,
showLabel: false
},
tabBarVisible: false,
labelStyle: { margin: 0, padding: 0 },
title: "",
tabBarIcon: ({ focused }) => <BtnPost style={{ marginTop: 15 }} />,
tabBarOnPress: ({ navigation, defaultHandler }) => {
}
}
},
thanks.. it is working.....
const AlertStack = createStackNavigator(
{
Alert: AlertScreen
},
);
AlertStack.navigationOptions = {
tabBarOnPress: () => {
alert('Hello');
},
};

Backhandler quits app instead of going back to relative screen

Using nested stacks when I go back to my homescreen, my homescreen briefly shows, then the app quits. Instead of hardcoding the route to go back to, how can I go back to my homescreen without quitting the app?
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
}
componentDidMount() {
BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
}
onBackPress = () => {
const { dispatch } = this.props;
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: "Home" })]
});
this.props.navigation.dispatch(resetAction);
};
App navigator:
const withHeader = (
screen: Function,
routeName: string,
Header
): StackNavigator =>
createStackNavigator(
{
[routeName]: {
screen,
navigationOptions: ({ routeName, props }) => ({
header: props => <Header {...props} />
})
}
},
{
initialRoute: "Home",
transparentCard: true,
cardStyle: {
backgroundColor: "transparent",
opacity: 1
},
transitionConfig: () => ({
containerStyle: {
backgroundColor: "transparent"
}
})
}
);
const routes = {
VideoEpisodes: {
screen: withHeader(VideoEpisodesScreen, "Video Episodes", DrawerHeader)
},
TestYourself: {
screen: withHeader(TestYourselfScreen, "Test Yourself", DrawerHeader)
},
MyResults: {
screen: withHeader(MyResultsScreen, "My Results", DrawerHeader)
},
BookmarkedVideos: {
screen: withHeader(
BookmarkedVideosScreen,
"Bookmarked Videos",
DrawerHeader
)
},
About: {
screen: withHeader(AboutScreen, "About", DrawerHeader)
}
};
const NestedDrawer = createDrawerNavigator(routes, config);
const MainStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
},
Drawer: {
screen: NestedDrawer,
navigationOptions: ({ props }) => ({
header: () => null
})
},
VideoPlayer: {
screen: VideoPlayerScreen,
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
}
},
{
initialRoute: "Home",
transparentCard: true,
cardStyle: {
backgroundColor: "transparent",
opacity: 1
},
transitionConfig: () => ({
containerStyle: {
backgroundColor: "transparent"
}
})
}
);
onBackPress = () => {
const { dispatch } = this.props;
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: "Home" })]
});
this.props.navigation.dispatch(resetAction);
return true
};

ReactNative Combining StackNavigation with DrawerNavigation

I am using both createStackNavigator & createDrawerNavigator but the stackNavigator isn't working i can't navigate to any page. here is the app.js
const DrawerNavigator = createDrawerNavigator({
homeScreen: {
screen: homeScreen,
navigationOptions: ({ navigation }) => {
return {
title: 'Home',
headerStyle: {
backgroundColor: '#231f20',
height: 0,
},
headerLeft: null,
gesturesEnabled: false,
}
},
},
categoryScreen: {
screen: categoryScreen,
navigationOptions: ({ navigation }) => ({
title: 'Makeup',
//title: navigation.getParam('category'),
headerStyle: {
backgroundColor: '#231f20',
},
headerTintColor: '#f5f5f5',
}),
},
categoryScreen: {
screen: categoryScreen,
navigationOptions: ({ navigation }) => ({
title: 'Photographers',
//title: navigation.getParam('category'),
headerStyle: {
backgroundColor: '#231f20',
},
headerTintColor: '#f5f5f5',
}),
},
},
{
contentOptions: {
activeTintColor: '#d03036',
activeBackgroundColor : '#f5f5f5',
inactiveBackgroundColor : 'rgba(0,0,0,0)',
inactiveTintColor: '#545f7a',
itemStyle: {
marginVertical: 0,
},
labelStyle: {
fontWeight:'bold',
backgroundColor: 'transparent'
}
},
headerMode: 'screen', // screen on android
// headerBackTitleVisible: false,
headerTransitionPreset: 'fade-in-place',
headerLayoutPreset: 'center',
cardStyle: {},
initialRouteName: 'homeScreen',
drawerPosition: 'left',
contentComponent: CustomDrawerContentComponent,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle'
});
const AuthStackNavigator = createStackNavigator(
{
loadingScreen: {
screen: loadingScreen,
navigationOptions: ({ navigation }) => {
return {
header: null,
}
},
},
loginScreen: {
screen: loginScreen,
navigationOptions: ({ navigation }) => {
return {
header: null,
}
},
},
DrawerNavigator: {
screen: DrawerNavigator,
navigationOptions: ({ navigation }) => {
return {
header: null,
gesturesEnabled: false
}
},
},
},
{
initialRouteName: 'loadingScreen',
// mode: 'modal',
headerMode: 'screen', // screen on android
// headerBackTitleVisible: false,
headerTransitionPreset: 'fade-in-place',
headerLayoutPreset: 'center',
cardStyle: {},
}
);
const NavigationApp = createAppContainer(AuthStackNavigator);
// Export the App
export default NavigationApp;
import { useScreens } from 'react-native-screens';
useScreens();
i tried exporting the DrawerNavigator but then the stacknavigator isn't working anymore can i use both at the same time ?
also i got design issue when doing so i tried searching for hours but with no luck

Couldn't get param in my tabs

I have Login and MAIN screen with 2 tabs...I'm passing user to MAIN screen with navigate('MAIN',{user: user} and I couldn't get that user in my MAIN with this.props.navigation.getParam('user'). My error is: undefined
When I debug with :
Reactotron.log(this.props); I'm getting undefined in my Main screen in constructor.
My code in App.js where is routes
const Routes = createStackNavigator(
{
Login: {
screen: Login,
navigationOptions: ({ navigation }) => ({
header: null,
}),
},
Main: {
screen: MainScreenRoutes,
navigationOptions: ({navigation}) => ({
header: null,
}),
},
},
{
initialRouteName: 'Login',
headerMode: 'screen',
navigationOptions: {
...HeaderStyles,
animationEnabled: true
}
}
);
export default Routes;
Code in MainRoutes:
let headerDefaultNavigationConfig = {
header: props => <CustomHeader {...props} />,
...HeaderStyles
};
const Tab1 = createStackNavigator(
{
Domov: {
screen: HomeScreen,
navigationOptions: {
},
},
},
{
navigationOptions: ({ navigation }) => ({
...headerDefaultNavigationConfig
}),
}
);
const Tab2 = createStackNavigator(
{
Dnevnik: {
screen: Diary,
navigationOptions: {
},
}
},
{
navigationOptions: ({ navigation }) => ({
...headerDefaultNavigationConfig
}),
}
);
const bottomTabs = createBottomTabNavigator(
{
Domov: Tab1,
Dnevnik: Tab2,
},
{
initialRouteName: "Domov",
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'Domov') {
//iconName = `home${focused ? '' : '-outline'}`;
iconName='home';
} else if (routeName === 'Dnevnik') {
//iconName = `ios-calendar${focused ? '' : '-outline'}`;
iconName='ios-calendar';
}
// if focused return view with line
if(focused) {
return (
<View style={styles.item}>
<Icon name={iconName} style={{fontSize: 20, color: '#FFF'}} />
<View style={styles.line}></View>
</View>
);
} else {
return(
<Icon name={iconName} style={{fontSize: 20, color: '#FFF'}} />
)
}
},
}),
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: 'white',
showLabel: false,
inactiveTintColor: '#4C2601',
style: {
backgroundColor: '#033D51',
},
labelStyle: {
fontSize: 12,
lineHeight: 30,
},
},
swipeEnabled: true,
});
const All = createStackNavigator(
{
"Home":{
screen: bottomTabs,
navigationOptions: {
header: null,
},
},
"MyProfil":{
screen: MyProfil,
navigationOptions: ({ navigation }) => ({
...headerDefaultNavigationConfig,
headerTitle: 'Moj profil',
}),
},
"Help": {
screen: Help,
navigationOptions: ({ navigation }) => ({
...headerDefaultNavigationConfig,
headerTitle: 'Pomoč',
}),
}
},
{
initialRouteName: 'Home',
headerMode: 'screen',
navigationOptions: {
...HeaderStyles,
animationEnabled: true
}
}
);
export default All;
Code in HomeScreen: That alert gives me undefined
constructor(props) {
super(props);
let user = props.navigation.getParam('user');
alert(user);
}
Code in Login.js where I navigate to that screen with tabs;
var obj = {
id: json.user.id,
lastname: json.user.lastname,
name: json.user.name,
email: json.user.email,
user: json.user.user,
};
_storeData(obj);
setTimeout(() => {
navigate("Main",{user: JSON.stringify(obj)});
},1300);
This is good :
this.props.navigation.navigate("HomeScreen", { user :user });
try this :
let user = props.navigation.state.params.user ;
EDIT :
as the constructor is called only one time for each app start try this
import _ from "lodash";
...
constructor(props){ super(props) ; console.log("main constructor ") ; ... }
componentWillReceiveProps(nextProps) {
console.log(JSON.stringify(nextProps.navigation.state.params))
if (_.has(nextProps, "navigation.state.params.user")) {
console.log(nextProps.navigation.state.params.user );
this.setState({ user: nextProps.navigation.state.params.user })
}
}
EDIT 2
in my createStackNavigator in dont have
navigationOptions: { header: null},
just simple stack1: { screen: stack1 },
but in my stack screen component i have this
export default class stack1 extends React.PureComponent {
static navigationOptions = ({ navigation }) => ({ header: null });
constructor (props) {
super(props);
this.state = { };
}
componentDidMount() {
this.setState({ obsToEdit: this.props.navigation.state.params.obs, dataready: true });
}
}

react-native nested StackNavigator passing parameters

I initially had this routing set up below with a tabNagivator and I was navigating to the 'Home' route and passing parameters using:
this.props.navigation.navigate('Home',{station:e,code:f,filter:'',filterName:'',offset:0});
Routing:
const PrimaryNav = TabNavigator({
Home: {
screen: LaunchScreen,
navigationOptions: {
swipeEnabled: false,
tabBarIcon: ({
tintColor
}) => ( <
Image source = {
require('../Images/trains.png')
}
style = {
[styles.icon]
}
/>
),
},
},
Map: {
screen: MapScreen,
navigationOptions: {
tabBarIcon: ({
tintColor
}) => ( <
Image source = {
require('../Images/locationTab.png')
}
style = {
[styles.icon]
}
/>
),
},
},
}, {
headerMode: 'none',
tabBarPosition: 'top',
animationEnabled: true,
tabBarOptions: {
showIcon: true,
showLabel: false,
activeTintColor: '#ffffff',
indicatorStyle: {
borderBottomColor: '#33b2f4',
borderBottomWidth: 3,
},
style: {
backgroundColor: '#000', // Makes Android tab bar white instead of standard blue
paddingTop: 5,
}
},
});
What I now want to do is replace 'LaunchScreen' in Home route with a stackNavigator but I don't know how to now pass the parameters to the stackNavigator down to the 'LaunchScreen':
const FeedStack = StackNavigator({
Launch: {
screen: LaunchScreen,
navigationOptions: {
header: null,
},
},
Tweets: {
screen: TweetScreen,
navigationOptions: {
title: 'Service Tweets',
headerTintColor: '#fff',
headerStyle: {
backgroundColor: '#000'
},
},
},
}, {
initialRouteName: 'Launch',
}
);
const PrimaryNav = TabNavigator({
Home: {
screen: FeedStack,
navigationOptions: {
swipeEnabled: false,
tabBarIcon: ({
tintColor
}) => ( <
Image source = {
require('../Images/trains.png')
}
style = {
[styles.icon]
}
/>
),
},
}...
I solved this by navigating to the route and storing the parameters in my mobX store bypassing the navigation parameters altogether.