React-native-navigation is not working correctly - react-native

I'm trying to make custom headerLeft button, But the thing is When I'm going to this specific, route without giving any errors or warnings, it is not working.
Here is my react-navigation stack
const Navigator = createStackNavigator({
Welcome: WelcomeScreen,
GetStarted: {
screen: GetStartedScreen,
},
CreatePassword: CreatePasswordScreen,
AlternatePhrase: {
screen:AlternatePhraseScreen,
navigationOptions: ({navigation}) => {
return {
headerLeft:<HeaderBackButton onPress={navigation.navigate("WelcomeScreen")} />
}
}
},
ConfirmPhrase: ConfirmPhraseScreen,
FanwallyAgreement: FanwallyAgreementScreen,
ImportWallet: ImportWalletFieldsScreen,
Main: MainScreen,
TokenDeposit,
});
Every other screens are working perfectly its just this one
`
AlternatePhrase: {
screen:AlternatePhraseScreen,
navigationOptions: ({navigation}) => {
return {
headerLeft:<HeaderBackButton onPress={navigation.navigate("WelcomeScreen")} />
}
}
},
`
Any suggestions on what am I doing wrong?

Try this
onPress={() => navigation.navigate("WelcomeScreen")}

Related

Call child react navigation prop from super component in react-native / react-navigation

I have a react native application using react navigation. I have following structure in my application.
class MainContainer extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<Header
backgroundColor={appcolors.primaryColor}
leftComponent={<TouchableOpacity onPress={() => this.props.navigation.toggleDrawer() }><Feather name='align-justify' size={24} color='white' /></TouchableOpacity>}
centerComponent={{ text: this.props.headerTitle , style: { color: 'white' } }}
/>
<MainDrawerNavigation/>
</View>
);
}
};
and <MainDrawerNavigation/> is a react navigation component as follows.
MainDrawerNavigation = createDrawerNavigator({
XScreen: {
screen: XScreen,
},
YScreen: {
screen: YScreen,
},
ZScreen: {
screen: ZScreen,
},
},{
}
});
I have got error when trying to call this.props.navigation.toggleDrawer() from MainContainer. Then for testing purpose I have add a button to XScreen and tried to toggle drawer and it was success. So I want to know is there any way to pass child navigation props to super view. So I could call this.props.navigation.toggleDrawer() method and control drawer from MainContainer. or any navigation practices that can be use to solve this.
PS: the error I got is _this2.props.navigation.toggleDrawer is not a function
In MainContainer, the this.props.navigation is not initiated, so you got such error. You can only access it inside the child component of MainDrawerNavigation i.e. XScreen, YScreen & ZScreen only.
For best practices you need to design how all component will navigate into your app and pass Navigator objects/components as root component.
There are multiple navigators, you will can read them react navigation api doc.
A simplified app needs SwitchNavigator, DrawerNavigator, TabBarNavigator & StackNavigator.
SwitchNavigator :
It is used for user authentication. It will give control to toggle between two component (FYI, component can be a Navigator or React.Component).
export const AuthNavigator = SwitchNavigator(
{
AuthLoading: { screen: AuthLoadingScreen },
App: { screen: AppDrawer},
Auth: { screen: AuthStack}
},
{
initialRouteName: 'AuthLoading',
}
);
for more details
DrawerNavigator :
It is used to display side panel or sliding view at left or right side of the screen. So, you can directly pass this component to SwitchNavigator's authentication successful screen.
export default const AppDrawer = DrawerNavigator(
{
Home: { screen: TabBarNav },
Notes: { screen: NotesStack },
Invite: { screen: InviteContactsStack },
Files: { screen: FilesStack },
Settings: { screen: SettingsStack }
},
{
initialRouteName: "Home",
contentOptions: {
activeTintColor: "#e91e63"
},
contentComponent: props => <LeftSidePanel {...props} />
}
);
TabBarNavigator :
It is used to display tab bar at bottom for iOS and at top for android by default. This can be customized.
export default const TabBarNav = TabNavigator(
{
ChatsTab: {
screen: ChatsStack,
navigationOptions: {
tabBarLabel: "Chats"
}
},
InviteContacts: {
screen: InviteContactsStack,
navigationOptions: {
tabBarLabel: "Invite"
}
},
Notifications: {
screen: NotificationsStack,
navigationOptions: {
tabBarLabel: "Notifications"
}
},
Tasks: {
screen: TasksStack,
navigationOptions: {
tabBarLabel: "Tasks"
}
}
},
{
tabBarPosition: "bottom",
}
);
StackNavigator :
It's name suggests that it will hold a stack of component. So, when any item is selected from drawer, you can directly put a StackNavigator in that screen.
export default const ChatsStack = StackNavigator({
Chats: {
screen: Chats
},
Messages: {
screen: Messages
}
});
You can read Spencer Carli's blog on medium which explain with code.
Please let me know whether it satisfies your need.

Custom header in nested TabNavigator

I have a fairly complication navigation flow requirement for an app I'm working on.
I have a bottom tab bar, for each tab I'll be having a top tab bar for additional related views.
Which I have working, however on the videos tab in the nested "All" tab, I need to add a search bar to the header, and on the "Favourites" tab I'll be having yet another custom header with an "Edit" button at the top right.
How can I achieve this navigation whilst allowing React Navigation to co-ordinate everything. See images below:
What I don't want to do is disable the header at the MainNavigator level and enable it for particular routes. Or even worse embed the header and the tab bar on individual containers.
routes.js
import {
StackNavigator,
TabNavigator,
DrawerNavigator
} from "react-navigation";
import Feed from "./containers/Feed";
import Auth from "./containers/Auth";
import News from "./containers/News";
import Videos from "./containers/Videos";
import FavouriteVideos from "./containers/FavouriteVideos";
const DashboardNavigator = TabNavigator(
{
Feed: {
screen: Feed
},
News: {
screen: News
}
},
{
tabBarPosition: "top"
}
);
const VideoNavigator = TabNavigator(
{
Videos: {
screen: Videos,
navigationOptions: {
title: "All"
}
},
Favourites: {
screen: FavouriteVideos
}
},
{
tabBarPosition: "top"
}
);
const MainNavigator = TabNavigator(
{
Dashboard: {
screen: DashboardNavigator,
navigationOptions: ({}) => ({
title: "Dashboard"
})
},
Video: {
screen: VideoNavigator,
navigationOptions: ({}) => ({
title: "Videos"
})
}
},
{
swipeEnabled: false,
animationEnabled: false,
tabBarPosition: "bottom"
}
);
const AuthenticatedNavigator = DrawerNavigator({
App: {
screen: MainNavigator
}
});
const RootNavigator = StackNavigator({
LoggedOut: {
screen: Auth
},
Authenticated: {
screen: AuthenticatedNavigator
}
});
export default RootNavigator;
Snack
https://snack.expo.io/H1qeJrLiM
Images
You can use react-navigation addListener function with combination setParams to achieve desired behavior.
You can listen for focus and blur events and then change a parameter. Then in your route config you can look for this parameter and decide what to render for header. I changed your snack to show a working example of what I am suggesting.
Example
const MainNavigator = TabNavigator(
{
Dashboard: {
screen: DashboardNavigator,
navigationOptions: ({}) => ({
title: "Dashboard"
})
},
Video: {
screen: VideoNavigator,
navigationOptions: ({navigation}) => {
let title = 'Videos';
navigation.state.routes.forEach((route) => {
if(route.routeName === 'Videos' && route.params) {
title = route.params.title;
}
});
// I set title here but you can set a custom Header component
return {
tabBarLabel: 'Video',
title
}
}
}
},
{
swipeEnabled: false,
animationEnabled: false,
tabBarPosition: "bottom"
}
);
export default class Videos extends Component {
constructor(props) {
super(props);
this.willFocusSubscription = props.navigation.addListener(
'willFocus',
payload => {
this.props.navigation.setParams({title: 'All Videos'});
}
);
this.willBlurSubscription = props.navigation.addListener(
'willBlur',
payload => {
this.props.navigation.setParams({title: 'Just Videos'});
}
);
}
componentWillUnmount() {
this.willFocusSubscription.remove();
this.willBlurSubscription.remove();
}
render() {
return (
<View>
<Text> Videos </Text>
</View>
);
}
}

React native TabNavigator navigation params

I want to send route params to Profile tab from button click action in Home screen. Below code is tab navigator
const Tabs = TabNavigator({
[routes.HOME]: {
screen: FeedMainScreen,
navigationOptions: {
tabBarLabel: tabBarLabels.HOME_TAB_LABEL,
},
},
[routes.SEARCH]: {
screen: SearchScreen,
navigationOptions: {
tabBarLabel: tabBarLabels.SEARCH_TAB_LABEL,
},
},
[routes.PROFILE]: {
screen: ProfileScreen,
navigationOptions: {
tabBarLabel: tabBarLabels.PROFILE_TAB_LABEL,
},
},
}
and button click navigation is like this
<Button onPress={() => this.props.navigation.navigate(routes.PROFILE, { id: this.props.user._id }, null)} />
and accsess param from Profile screen like this
constructor (props) {
super(props)
console.log('NavPrams', this.props.navigation.state)
}
alwaya undifined
You can use connect() method to successfully map the props and use them anywhere.
Add the below mentioned code in the class where is written -
const mapStateToProps = state => {
return {
user: this.props.user;
};
};
export default connect(mapStateToProps, {})(className);

My React-Native navigation just wont style

I have an issue that no matter what I try, I just cannot get styling to work on my Stack with Drawer navigator. I've tried several examples and solutions but just none of them work, my navigation stays the default blue.
In my current code below, I've left 2 coloring options open - those two are of the many things I've tried before.
I hope that someone knows what's going on because I'm starting to get clueless.
const MainScreenNavigator = StackNavigator({
'Home': {
screen: Components.HomeScreen,
navigationOptions: ({navigation}) => ({
header: <Components.StackHeader title='Home' navigation={navigation} />
})
},
'Scan': {
screen: Components.ScanScreen,
navigationOptions: ({navigation}) => ({
header: <Components.StackHeader title='Scan QR' navigation={navigation} />
})
},
'LockInfo': {
screen: Components.LockInfoScreen,
navigationOptions: ({navigation}) => ({
header: <Components.StackHeader title='Lock' navigation={navigation} />
})
},
});
const RootNavigator = DrawerNavigator ({
Home: {
screen: MainScreenNavigator,
},
});
RootNavigator.navigationOptions = {
contentOptions: {
activeBackgroundColor: '#ff5976',
style: {
backgroundColor: '#000000'
}
}
}
const ModalNavigator = StackNavigator(
{
Main: { screen: Main },
Login: { screen: Login },
},
{
headerMode: 'none',
mode: 'modal',
navigationOptions: {
gesturesEnabled: false,
},
https://reactnavigation.org/docs/navigators/stack#Screen-Navigation-Options
checkout this above link, search and add the required styling properties inside your own StackNavigator, headerStyle, headerTitleStyle, headerBackTitleStyle, headerTintColor and so on...
Also for DrawerNavigator, checkout this below link and replicate the code, styling properties for the same are provided.
https://reactnavigation.org/docs/navigators/drawer#DrawerNavigator
Also remove the single inverted commas from Home, Scan and LockInfo

How to back from Facebook in drawerNavigator [react-native]

i created drawer navigator and one of option is open facebook page (from app or URL) it's work fine but after the openning facebook page i try to go back and its threwing error..
i try try to fix that with return null after 'catch' and the error disappeare but its return to null page and i need to click back again to actually return to the right page.
what can i do to fix that?
class Root extends Component {
render(){
const { navigation } = this.props.navigation;
const Drawer = DrawerNavigator({
Home:{
screen: HomeScreen,
navigationOptions: {
drawerLabel: 'home',
},
},
FacebookPage: {
screen: () => { Linking.canOpenURL('fb://page/1000000000')
.then((supported) => {
if (!supported) {
Linking.openURL('http://facebook.com/1000000000/')
} else {
Linking.openURL('fb://page/1000000000')
}})
.catch(err => Alert.alert(err))
},
navigationOptions: {
drawerLabel: 'Facebook',
},
},
MyAccount:{
screen: MyAccountScreen,
navigationOptions: {
drawerLabel: "My account",
},
},
},
{
initialRouteName: 'Home',
});
return(
<Drawer/>
)}
}
export default Root;