I can't show my custom header with static navigation options. It's only TabNavigator on my Title. What should I do?
This is my HomeScreen Component;
export default class Home extends Component {
static navigationOptions = ({navigation}) => ({
title: 'MENEMENOYS',
headerLeft : (
<TouchableOpacity
onPress={() => {
AuthStore.LogOut().then(() => {
navigation.navigate('LoginPage');
});
}}>
<Icon
name="md-log-out"
size={30}
color={'white'}
style={{marginLeft:10}}
/>
</TouchableOpacity>
)
})
And this is my router : stack navigator with tab navigator.
const TabNavigator = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon
name="md-home"
size={30}
color={tintColor}
style={styles.homeIcon}
/>
),
},
},
AddNewCar: {
screen: AddNewCar,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon
name="md-add-circle"
size={40}
color={tintColor}
style={styles.addIcon}
/>
),
},
},
OtoparkList: {
screen: OtoparkList,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<IconAwesome name="car" size={30} color={tintColor} />
),
},
},
},
{
tabBarOptions: {
showLabel: false,
activeTintColor: '#41AB5F',
inactiveTintColor: 'white',
style: {
backgroundColor: '#1F202D',
borderTopColor: 'transparent',
},
},
},
);
const AppNavigator = createStackNavigator(
{
TabNavigator: {
screen: TabNavigator,
navigationOptions: {
}
},
LoginPage: {
screen: LoginPage,
navigationOptions: {
headerShown: false,
},
},
ParkingDetail: {
screen: ParkingDetail,
navigationOptions: {
headerShown: false,
},
},
Print: {
screen: Print,
navigationOptions: {
headerShown: false,
}
}
},
{
initialRouteName: 'LoginPage',
},
);
But my header is not shown. Only Header title:TabNavigator and default back button.
Where am i doing wrong ? Please help me. Thanks.
Hey in React navigation latest version 5.x syntax is changed try following
Take a look at doc here Header buttons
static navigationOptions = ({ navigation }) => {
return {
headerTitle: () =>(
<View>
<Text>MENEMENOYS</Text>
</View>
),
headerLeft: () => (
<TouchableOpacity
onPress={() => {
AuthStore.LogOut().then(() => {
navigation.navigate('LoginPage');
});
}}>
<Icon
name="md-log-out"
size={30}
color={'white'}
style={{marginLeft:10}}
/>
</TouchableOpacity>
),
};
};
Related
I'm using react-navigation v4 for my expo App. For my App I'm using createDrawerNavigator and createSwitchNavigator with createAppContainer and createBrowserApp for web.
My issue is when I'm navigating to a route where I don't want params, there also it's passing me parameters. like,
http://localhost:19006/App/SkyView (first I visited route without
params)
http://localhost:19006/App/CasesList (I visited another route, from
there I'm passing params to SkyView route)
it redirect me to http://localhost:19006/App/SkyView?caseId=HYDE200627-00064&tripIndex=0
after that If I want to visit http://localhost:19006/App/SkyView it navigating to http://localhost:19006/App/SkyView?caseId=HYDE200627-00064&tripIndex=0
My DrawerNavigator code
const DrawerNavigation = createDrawerNavigator({
CasesList: {
screen: MainAuth(CasesList),
navigationOptions: {
drawerIcon: ({ tintColor }) => (<FontAwesome5 name='map-marked-alt' size={18} style={{color:tintColor}}/>)
}
},
SkyView: {
screen: MainAuth(SkyView),
navigationOptions: {
drawerIcon: ({ tintColor }) => (<FontAwesome5 name='map-marked-alt' size={18} style={{color:tintColor}}/>)
}
},
},{contentComponent: props => <CustomDrawerContentComponent {...props}/>,contentOptions: {
activeTintColor: baseColor,
itemsContainerStyle: {
marginVertical: 0,
},
iconContainerStyle: {
opacity: 1
}
}})
const CustomDrawerContentComponent = props => {
const signOutAsync = async () => {
try {
store.dispatch(logoutHandler())
props.navigation.navigate('Auth');
}
catch(exception) {
console.log(exception)
}
};
return (
<ScrollView contentContainerStyle={styles.container}>
<SafeAreaView
forceInset={{ top: 'always', horizontal: 'never' }}
>
<View style={styles.header}>
<View style={styles.avatar}>
<FontAwesome5 name="user-alt" size={24} style={{color:white}}/>
</View>
<View style={styles.userInfo}>
<Text style={{}}>Abdulla Zulqarnain</Text>
</View>
</View>
<DrawerItems {...props} />
</SafeAreaView>
<TouchableOpacity onPress={()=>signOutAsync()}>
<View style={styles.item}>
<View style={styles.iconContainer}>
<FontAwesome5 name='sign-out-alt' size={18} style={{color:red_dark}}/>
</View>
<Text style={styles.label}>Logout</Text>
</View>
</TouchableOpacity>
</ScrollView>
);
}
other Routing code
const routes = createSwitchNavigator(
{
AuthLoading: {
screen: AuthLoadingScreen,
navigationOptions: {
header: null,
}
},
App: {
screen: DrawerNavigation,//MainAuth(CasesList),
navigationOptions: {
header: null,
}
},
Auth:{
screen: Login,
navigationOptions: {
tabBarVisible: false,
header: null,
},
},
HospitalList: {
screen: HospitalList,
navigationOptions: {
header: null,
}
},
},
{
initialRouteName: 'AuthLoading',
defaultNavigationOptions: {
}
}
);
const container = isWeb ? createBrowserApp(routes): createAppContainer(routes);
I'm stuck since 2 days can anyone help me to sortout this issue.
I'm using a tab bottom navigator in my project. I want to show a new page in a tab of the tab bottom navigator but I want the tab navigator to appear again at the bottom. I don't want to add the button of the new page I want to show below. How do I manage this situation.I created the new scene as another js file and added it to the app js. I mean. I have a button to redirect to a new page in the Home tab, but how do I navigate
my navigator codes in app.js:
import LoadingScreen from './screens/LoadingScreen'
import HomeScreen from './screens/HomeScreen'
import LoginScreen from './screens/LoginScreen'
import RegisterScreen from './screens/RegisterScreen'
import ProfileScreen from './screens/profileScreen'
import NotificationScreen from './screens/notificationScreen'
import PostScreen from './screens/postScreen'
import soruOnaylaScreen from './screens/soruOnaylaScreen'
const AppContainer = createStackNavigator(
{
default: createBottomTabNavigator(
{
soruOnayla: {
screen: soruOnaylaScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<Ionicons name="ios-chatboxes" size={24} color={tintColor} />
}
},
Home: {
screen: HomeScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<Ionicons name="ios-home" size={24} color={tintColor} />
}
},
Post: {
screen: PostScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<Ionicons
name="ios-add-circle"
size={36}
color='#E9446A'
style={{
shadowColor: "#E9446A",
shadowOffset: { width: 0, height: 0 },
shadowRadius: 10,
shadowOpacity: 0.3
}}
/>
}
}
, Notification: {
screen: NotificationScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<Ionicons name="ios-notifications" size={24} color={tintColor} />
}
},
Profile: {
screen: ProfileScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<Ionicons name="ios-person" size={24} color={tintColor} />
}
}
},
{
tabBarOptions: {
activeTintColor: "#161f3d",
inactiveTintColor: "#b8bbc4",
}
}
),
postModal: {
screen: PostScreen
}
},
{
mode: "modal",
headerMode: "none"
}
)
const AuthStack = createStackNavigator({
Login: LoginScreen,
Register: RegisterScreen
})
export default createAppContainer(
createSwitchNavigator(
{
Loading: LoadingScreen,
App: AppContainer,
Auth: AuthStack
},
{
initialRouteName: "Loading"
}
)
)
I been having an issue with navigating from API flat list to separate screen. I got a news api integrated and I want to from each article render to navigate to newsdetail screen. I'm not getting an error message only touchable opacity is not working. I'm not sure where I made a mistake in the flatlist or in the APP.js
FlatList:
import React, { Component } from 'react';
import { FlatList, TouchableOpacity } from 'react-native';
import { getUSANews } from './fetchNews';
import Article from './Article';
import NewsDetail from '../screens/NewsDetail';
class News extends Component {
state = {
articles: [],
refreshing: true
};
componentDidMount = () => {
this.fetchNews();
};
fetchNews = () => {
getUSANews()
.then(articles => {
this.setState({ articles, refreshing: false });
})
.catch(() => this.setState({ refreshing: false }));
};
handleRefresh = () => {
this.setState({ refreshing: true }, () => this.fetchNews());
};
render(navigation) {
return (
<FlatList
data={this.state.articles}
keyExtractor={item => item.url}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh}
renderItem ={({item}) => {
return (
<TouchableOpacity onPress={() => this.props.navigation.navigate('NewsDetail')}
>
<Article article={item} />
</TouchableOpacity>
);
}}
/>
);
}
}
export default News;
App.js:
const Drawer = createDrawerNavigator(
{
Home: {
screen: homeScreen,
Options: {
title: 'Home',
activeTintColor: 'red'
},
},
Signin:{
screen: SigninScreen,
Options: {
title: "Sign In",
},
},
Signup: {
screen: SignupScreen,
navigationOptions: {
title: 'Sign Up'
}
}
},
{
initialRouteName: 'Home',
unmountInactiveRoutes: true,
headerMode: 'none',
contentOptions: {
activeTintColor: 'red'
},
},
);
const AppNavigator = createStackNavigator({
Drawer: {
screen: Drawer,
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Home",
headerTitleStyle: {
color: "white"
},
headerStyle: {
backgroundColor: "#5BBC9D"
},
headerLeft: (
<Icon
onPress={() => navigation.openDrawer()}
name="md-menu"
color="white"
size={30}
style={{
paddingLeft: 10
}}
/>
),
headerRight: (
<Icon
onPress={() => navigation.se()}
name="ios-search"
color="white"
size={30}
style={{
paddingRight: 10
}}
/>
)
}
}},
Detail: {
screen:NewsDetail
}
})
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render (){
return(
<AppContainer />
);
}
}
You don't have any screen name NewsDetail change this:
onPress={() => this.props.navigation.navigate('NewsDetail')}
to
onPress={() => this.props.navigation.navigate('Detail')}
Hope this helps!
You set the RouteName to your newsDetail screen as Detail. Hence to navigate to that screen you need to use the RouteName you set and not the screen name. Kindly change from;
onPress={() => this.props.navigation.navigate('NewsDetail')}
to
onPress={() => this.props.navigation.navigate('Detail')}
When I am trying to do setParams with navigation in componentDidMount() and try to access in static navigationOptions = {} but it's not setting the params in navigation state object and getting undefined.
I am currently using below version
react-navigation 3.9.1
react-native Using with EXPO SDK 32.0
ManTabNavigator.js
const HomeStack = createStackNavigator({
Home: { screen: HomeScreen },
Service: { screen: ServiceListScreen },
}, {
initialRouteName: 'Home',
});
HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
type={'MaterialIcons'}
name={'home'}
/>
),
export default createBottomTabNavigator({
HomeStack,
LinksStack,
SettingsStack,
}, {
initialRouteName: 'HomeStack',
activeColor: '#19CF86',
inactiveColor: 'rgba(0, 0, 0, 0.3)',
barStyle: { backgroundColor: '#ffffff' },
});
};
ServiceListScreen.js
class ServiceListScreen extends Component {
static navigationOptions = {
header: ({ navigation }) => {
return (
<Header>
<ServiceTab
services={{}}
/>
</Header>
)
}
};
_setNavigationParams() {
let title = 'Form';
this.props.navigation.setParams({
title,
});
}
componentDidMount() {
this._setNavigationParams();
}
render() {
const { selectedService } = this.props;
return (
<KeyboardAwareScrollView>
<SafeAreaView
// style={styles.container}
forceInset={{ top: 'always' }}
>
<View style={{ flex: 1 }}>
<SubServiceList
selectedService={selectedService}
/>
</View>
</SafeAreaView>
</KeyboardAwareScrollView>
);
}
}
ServiceListScreen.propTypes = {
services: PropTypes.object,
selectedService: PropTypes.object,
// actions
};
const mapStateToProps = (state, ownProps) => {
return {
services: getAllServices(state),
selectedService: getSelectedServices(state),
};
}
export default compose(
withNavigation,
connect(mapStateToProps),
)(ServiceListScreen);
navigationOptions is not the same as the navigation params. If you don't need to dynamically set the title, you could do this instead:
static navigationOptions = {
title: 'Form',
header: () => (
<Header>
<ServiceTab services={{}} />
</Header>
)
}
If you do need access to the navigation params, then do so like this:
static navigationOptions = ({ navigation }) => ({
title: navigation.getParam('title', ''), // fallback to empty string
header: () => (
<Header>
<ServiceTab services={{}} />
</Header>
)
})
this is how i use navigationOptions
static navigationOptions = ({ navigation }) => {
return {
title: navigation.state.params.type ? navigation.state.params.type : 'Members',
headerStyle: {
backgroundColor: Colors.primaryColor,
},
headerTintColor: Colors.white,
headerTitleStyle: {
fontWeight: 'bold',
},
headerMode: 'float',
headerLeft: <Icon
onPress={() => navigation.goBack()}
name="arrow-back"
type='MaterialIcons'
style={{ color: 'white', marginLeft: 10 }}
/>,
}
}
make sure you are getting params correctly from navigation
format: title: navigation.state.params.title
I am learning to use React Navigation and loving it, but can't figure out how to send props from my top level App Component down to my screen components. I could be (most probably) going about it completely the wrong way. Here is my code.
Main App Component
class App extends Component {
constructor(props) {
super(props);
this.state = {
signedIn: false,
checkedSignIn: false
};
}
componentWillMount() {
isSignedIn()
.then(res => this.setState({ signedIn: res, checkedSignIn: true }))
.catch(err => alert(err));
}
render() {
const { checkedSignIn, signedIn } = this.state;
if (!checkedSignIn) {
return null;
}
if (signedIn) {
console.log("yeah boi");
console.log(SignedOut);
return (
<Provider store={store}>
<SignedIn screenProps={(name = "TestName")} />
</Provider>
);
} else {
console.log("nah bro");
return (
<Provider store={store}>
<SignedOut />
</Provider>
);
}
}
}
Screen
export default ({ navigation }) =>
<View style={{ paddingVertical: 20 }}>
<Card title="John Doe">
<View
style={{
backgroundColor: "#bcbec1",
alignItems: "center",
justifyContent: "center",
width: 80,
height: 80,
borderRadius: 40,
alignSelf: "center",
marginBottom: 20
}}
>
<Text style={{ color: "white", fontSize: 28 }}>JD</Text>
</View>
<Button
title="SIGN OUT"
onPress={() =>
onSignOut().then(() => navigation.navigate("SignedOut"))} // NEW LOGIC
/>
</Card>
</View>;
Nav
export const SignedIn = TabNavigator({
Tasks: {
screen: Tasks,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="list" size={30} />
}
},
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="home" size={30} />
}
},
Message: {
screen: Message,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="envelope-letter" size={30} />
}
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="user" size={30} />
}
}
});
Can anyone tell me how I would pass props, such as my attempted {(name = "TestName")}, to the SignedIn SFC?
I am fairly new to react so please be gentle :)
Thanks
Sam
Got it sorted while still keeping the items stateless, using React Navigations screenProps parameter. Just had to fix my syntax in the Nav component and explicitly call screenProps in my screen. Here it is for reference:
Main App
class App extends Component {
constructor(props) {
super(props);
this.state = {
signedIn: false,
checkedSignIn: false
};
}
componentWillMount() {
isSignedIn()
.then(res => this.setState({ signedIn: res, checkedSignIn: true }))
.catch(err => alert(err));
}
render() {
const { checkedSignIn, signedIn } = this.state;
if (!checkedSignIn) {
return null;
}
if (signedIn) {
console.log("yeah boi");
console.log(SignedOut);
return (
<Provider store={store}>
<SignedIn screenProps={{ name: "TestName" }} />
</Provider>
);
} else {
console.log("nah bro");
return (
<Provider store={store}>
<SignedOut />
</Provider>
);
}
}
}
Screen
export default ({ navigation, screenProps }) =>
<View style={{ paddingVertical: 20 }}>
<Card title={screenProps.name}>
<View
style={{
backgroundColor: "#bcbec1",
alignItems: "center",
justifyContent: "center",
width: 80,
height: 80,
borderRadius: 40,
alignSelf: "center",
marginBottom: 20
}}
>
<Text style={{ color: "white", fontSize: 28 }}>JD</Text>
</View>
<Button
title="SIGN OUT"
onPress={() =>
onSignOut().then(() => navigation.navigate("SignedOut"))} // NEW LOGIC
/>
</Card>
</View>;
Nav
export const SignedIn = TabNavigator({
Tasks: {
screen: Tasks,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="list" size={30} />
}
},
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="home" size={30} />
}
},
Message: {
screen: Message,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="envelope-letter" size={30} />
}
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name="user" size={30} />
}
}
});
Use store state to get data, set state of store in top level component,
use that state in your screen component
I think <SignedIn screenProps={(name = "TestName")} /> will rise a syntax error. It should be just <SignedIn name='TestName' />. The bigger problem is how you use the TabNavigator component. What if you try the following:
export const SignedIn = ({ name }) => TabNavigator({
Tasks: {
screen: Tasks,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name={ name } size={30} />
}
},
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name={ name } size={30} />
}
},
Message: {
screen: Message,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name={ name } size={30} />
}
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarIcon: ({ tintColor }) =>
<SimpleLineIcons name={ name } size={30} />
}
}
});