i want to logout from a component inside a stacknavigator and the stacknavigator is inside a bottomtabsnavigator which is finally inside a stacknavigator that houses two switchnavigator
i tried this.props.navigation.navigate(component) and it failed and several other ways i am a bit stuck and frustrated any help will be greatly appreciated as i am new to react native and react navigation
const AddContactTab = createStackNavigator({
AddContact: AddContactsActivity,
});
const ManageContactsTab = createStackNavigator({
ManageContacts: ManageContactsActivity,
viewContact: ViewSingleContactsActivity,
editContacts: EditContactsActivity
});
const Tabs = createBottomTabNavigator({
ManageContacts: ManageContactsTab,
AddContact: AddContactTab
}, {
tabBarOptions: {
activeBackgroundColor:'#3F51B5',
activeTintColor:'#ccc',
showLabel:false,
style: {
backgroundColor:'white',
color:'white'
},
tabStyle:{
},
// labelStyle:{
// color:'white',
// fontWeight: 'bolder',
// fontSize: 14
// }
},
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: () => {
const { routeName } = navigation.state;
let tabName;
tabName = routeName === 'AddContact' ? 'plus' : 'home';
return <Icon name={tabName} size={24}
color="grey" />
}
})
},
);
export default createAppContainer(Tabs);
const MainStack = createStackNavigator(
{
Home: { screen: HomeActivity },
Register: {screen: RegistrationActivity}
},
{
initialRouteName: 'Home',
}
);
const AuthStack = createStackNavigator(
{
Dashboard: { screen: DashboardActivity },
},
{
initialRouteName: 'Dashboard',
}
);
const RootStack = createSwitchNavigator({
initialLoading: InitialLoadingActivity,
auth: AuthStack,
all: MainStack,
},
{
initialRouteName: 'initialLoading',
});
now i want to logout from addcontactsactivity to the initialroute of the AuthStack stack navigator....please if i am not clear enough let me know so i can edit my question
Regarding documentation I guess you can try:
this.props.navigation.dispatch(StackActions.popToTop())
The popToTop action takes you back to the first screen in the stack, dismissing all the others.
Documentation
You need to reset your present stack.
Set the present stack index to 0
Got to the parent stack which has access of all the screens
Navigate to that screen.
import { StackActions, NavigationActions } from 'react-navigation';
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Profile' })],
});
this.props.navigation.dispatch(resetAction);
Edit : Use this if it works for you.
this.props.navigation.dispatch(
{
type: 'Navigation/NAVIGATE',
routeName: 'GoToANavigator',
action: {
type: 'Navigation/NAVIGATE',
routeName: 'GoToAScreenInANavigator',
}
}
);
ref
ref 2
Related
In my react native app I am using TabNavigator inside a StackNavigator as so:
const AppTabs = createBottomTabNavigator(
{
Home: Tab1,
Create: Tab2,
Search: Tab3,
Ask: Tab4
}
);
const AppStack = createStackNavigator(
{
Tabs: AppTabs,
Screen2: SecondScreen,
Screen3: ThirdScreen,
},
{
initialRouteName: "Tabs"
}
);
This works fine but when I try to use another StackNavigator for the Search Tab, two headers are displayed and the only solution I have found is to hide the nested StackNavigator's header with headerMode: "none":
const SearchStack = createStackNavigator(
{
Search: SearchScreen,
Post: PostScreen,
},
{
headerMode: "none",
navigationOptions: {
headerShown: false
},
initialRouteName: "Search"
}
);
However, this functionality is not best for my app. I need the outside StackNavigator's header to be hidden instead when the Search tab is in focus so the user can still go back and forth between screens in the nested Search Stack. Can someone advise me what I should do to achieve this?
I think you are using react-navigation in the wrong way, you should not make separate stack navigator for SearchStack, instead you should add SearchStack's screens in AppStack only.
const AppTabs = createBottomTabNavigator(
{
Home: Tab1,
Create: Tab2,
Search: Tab3,
Ask: Tab4
}
);
const AppStack = createStackNavigator(
{
Tabs: AppTabs,
Post: PostScreen,
Screen2: SecondScreen,
Screen3: ThirdScreen,
},
{
initialRouteName: "Tabs"
}
);
Change your AppStack navigator to the following:
const AppStack = createStackNavigator(
{
Tabs: AppTabs,
Screen2: SecondScreen,
Screen3: ThirdScreen,
},
{
defaultNavigationOptions: ({navigation}) => {
const currentRoute = navigation.state.routes[navigation.state.index];
const {routeName} = currentRoute;
let tabBarVisible = true;
if (routeName === 'Search') {
tabBarVisible = false;
}
return {
headerShown: tabBarVisible,
};
},
initialRouteName: 'Tabs',
},
);
If the app is rendering the Search route, the headerShown property of your top most StackNavigator (AppStack) will be set to false. Meaning the app will not show the AppStack header when rendering the Search route.
The SearchStack navigator can be defined simply like this:
const SearchStack = createStackNavigator(
{
Search: SearchScreen,
Post: PostScreen,
},
{
initialRouteName: 'Search',
},
);
Simply use below code in the page you want to hide the header
export default class SearchScreen extends Component {
static navigationOptions = {
header: null
}
}
I have been having some problems passing parameters from a screen in a switchNavigator to another in a TabNavigator
setvalue(response){
this.setState({profile :response})
console.warn(this.state.profile);
this.state.navigate('Navigators',{profile: profile})
}
The profile contains a JSON object of profile details. The navigation sends the date to the 'Navigators' screen which is just a TabNavigator
const Navigators = createAppContainer(Userstack);
export default RootStack = createSwitchNavigator(
{
Home: {
screen: Login
},
Register: {
screen: Registration
},
Navigators: {
screen: Navigators
},
},
{
initialRouteName: 'Home'
}
);
How the TabNavigator is created.
export default Userstack = createBottomTabNavigator(
{
User: {
screen: Profile
},
Discovery: {
screen: DiscoveryNavigator
},
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ tintColor }) => {
const { routeName } = navigation.state;
let IconComponent = Ionicons;
let iconName;
if (routeName === 'User') {
iconName = `md-contact`;
IconComponent = HomeIconWithBadge;
} else if (routeName === 'Discovery') {
iconName = `md-search`;
}
return <IconComponent name={iconName} size={27} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: '#00FA9A',
inactiveTintColor: 'black',
},
}
);
The screen I wish to access the profile information is
export default class Profile extends Component {
constructor(props){
super(props);
console.warn(props)
this.State = {
profile: this.props.navigation.params.profile
}
}
Did you try this.props.navigation.state.params?
According to Reference: https://reactnavigation.org/docs/params.html,
You can also directly access the params object with this.props.navigation.state.params. This may be null if no params were supplied, and so it's usually easier to just use getParam so you don't have to deal with that case.
Hope it's ok.
I Can't understand how custom header it's supposed to work.
I just want to send static properties to my Header depending on which route is selected.
I have:
export default AppNavigator = StackNavigator({
Index:{
screen: BottomNavigator,
}
},{
navigationOptions: {
header: AppHeader,
},
headerMode:'float',
})
And my BottomNavigator is:
const BottomNavigator = TabNavigator({
TabMenu1: {
screen: () => <Text> Resumé </Text>,
navigationOptions: {
title: 'Resumé'
}
},
TabMenu2: {
screen: () => <Text> Sells </Text>,
navigationOptions: {
title: 'Sells'
}
},
},{
tabBarComponent: BottomNavigation
});
I'm expecting {props.title} in my custom header, is that right?
Additional info: My full route stack is:
AuthNavigator have a wrapper that is connected to redux and have:
const AuthNavigator = StackNavigator({
SignedIn: {
screen: MainNavigator
}
},{
headerMode:'none',
initialRouteName: 'SignedIn'
});
MainNavigator:
const MainNavigator = StackNavigator({
Drawer: {
screen: DrawerNav
},
}, {
headerMode:'none',
});
DrawerNav:
const DrawerNav = DrawerNavigator({
Menu1: {
screen: AppNavigator
},
}, {
contentComponent: DrawerNavigation,
drawerWidth: 300
});
AppNavigator and BottomNavigator are described above
for React Navigation 5 this works
props.scene.descriptor.options.title
You can specify title like this :
RouteName:
{
screen: RouteScreen,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title || 'StaticTitle'
})
}
Where navigation.state.params.title is the title you send as a params when you navigate (so if you want to add a variable for exemple). If you just want to use a static title, just use title: 'StaticTitle'
export const Navigator = StackNavigator(routes, {
headerMode: 'screen',
navigationOptions: ({ navigation }) => ({
header: props => <Header {...props} />,
}),
})
I did find a work around but it seems pretty verbose for what seems to be a common use case..
// Header.js
...
render() {
const { getScreenDetails, scene } = this.props
const details = getScreenDetails(scene)
return (
<View>
<Text>{details.options.title}</Text>
<View>
)
Resolved with a code extracted of Header.js file of react-navigation:
The right way to get the title inside a custom header is:
const sceneOptions = props.getScreenDetails(props.scene).options;
const sceneTitle = sceneOptions.title;
Thanks all!
I want to navigate to to the same screen but with different params.
so imagine
navigate to MyRouteName
on this screen click a button which should navigate me to MyRouteName but with different params.
currently I've tried
this.props.navigation.navigate('MyRouteName', {param1: 'new val'})
and
const setParamsAction = NavigationActions.setParams({
params: { param1: 'new val'},
key: 'mrn-new_val',
})
this.props.navigation.dispatch(setParamsAction)
Neither work. Neither the docs nor github issues I found provide clear guidance on this.
How do i accomplish this?
Update: in response to comment below
I'm using a stacked Navigator as my root, which leads to a DrawerNavigator
// MyDrawer.js
// ...
const MyDrawer = DrawerNavigator(
{
MyRouteName: {
screen: MyScreen,
},
},
{
initialRouteName: 'MyRouteName',
contentOptions: {
activeTintColor: '#e91e63',
},
contentComponent: props => <DrawerScreen {...props}/>,
}
);
export default MyDrawer;
// MyScreen.js
class MyScreen extends React.Component{
//..
//.. stuff goes here
//..
drillDown(newVal){
const setParamsAction = NavigationActions.setParams({
params: { param1: newVal },
key: 'ms-${newVal}',
})
this.props.navigation.dispatch(setParamsAction)
}
//..
//.. more stuff
//..
}
My final implementation based on #benneygenel's answer below.
const MyDrawer = DrawerNavigator({
MyRouteName: {
screen: StackNavigator({
DrillDown:{
screen: MyScreen,
},
}, {
headerMode: 'none',
}),
},
});
(MyScreen defines it's own header)
You can use a StackNavigator inside the Drawer and navigate like a normal StackNavigator.
const MyDrawer = DrawerNavigator({
MyRouteName: {
screen: StackNavigator({
DrillDown: {
screen: MyScreen
}
}),
},
});
export default MyDrawer;
I have list of users , each user has its display image in the list.
What I am trying is whenever user presses the display image , get redirected to his/her profile through stackNavigation .
CustomTabView:
const CustomTabView = ({ router, navigation }) => {
const { routes, index } = navigation.state;
const ActiveScreen = router.getComponentForState(navigation.state);
const routeNav = addNavigationHelpers({
...navigation,
state: routes[index],
});
const routeOptions = router.getScreenOptions(routeNav, 'tabBar');
return (
<View style={styles.container}>
<CustomTabBar
navigation={navigation}
activeRouteName={routes[index].routeName}
icon={routeOptions.tabBarIcon}
/>
<ActiveScreen
navigation={addNavigationHelpers({
...navigation,
state: routes[index]
})}
/>
</View>
);
};
StackNavigator: // goToProfile.js // also tried placing in index.anndroid.js but didnt found a way to export
const goToProfile = StackNavigator({
Profile: {
screen: Profile,
navigationOptions: ({ navigation }) => ({
title: `${navigation.state.params.person.name.first} ${navigation.state.params.person.name.last}`
})
},
})
custom tabs: //index.android.js
const CustomTabRouter = TabRouter(
{
Chat: {
screen: Chats,
path: ""
},
Status: {
screen: Contacts,
path: "notifications"
},
Camera: {
screen: Camera,
path: "settings"
}
},
{
initialRouteName: "Chat",
},
);
const CustomTabs = createNavigationContainer(
createNavigator(CustomTabRouter)(CustomTabView)
);
Also my component :
<TouchableOpacity
onPress = { () => this.props.navigation.navigate('Profile', { item } ) } >
<Avatar
source={{ uri: item.picture.thumbnail }}
/>
</TouchableOpacity>
Your Stack Navigator will look like this:
const ChatStack= StackNavigator({
Chat:{screen: Chat,
navigationOptions: {
header: null,
}},
Profile: {
screen: Profile,
navigationOptions: ({ navigation }) => ({
title: `${navigation.state.params.person.name.first} ${navigation.state.params.person.name.last}`,
tabBarVisible: false
// depending if you want to hide the tabBar on the profile page if not remove it.
})
},
})
Then Your customTab will take this shape:
const CustomTabRouter = TabRouter(
{
Chat: {
screen: ChatStack,
},
Status: {
screen: Contacts,
path: "notifications"
},
Camera: {
screen: Camera,
path: "settings"
}
},
.........
With those changes you should be able to navigate to Profile screen with your
this.props.navigation.navigate('Profile', { item } )
You want to dispatch a navigation action, not render a new stack - Although I'm not sure your navigators are properly constructed for this to succeed...
_goToProfile = (person) => {
<goToProfile navigate={this.props.navigation} />
}
should be
_goToProfile = (person) => {
this.props.navigation.navigate('Profile', person)
}