Unable to remove existing params in react navigation - reactjs

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.

Related

Flat List navigation react native

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')}

Can't show custom header in tabNavigator

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>
),
};
};

react-navigation Custom Drawer not rerender

Style styles.draweritemstxt_active and styles.draweritemstxt_inactive not set / rerender when I try to choose other drawer item.
Navigator.js
const MainDrawer = DrawerNavigator({
Event: { screen: EventScreen },
Wallet: { screen: WalletScreen},
Profile: { screen: ProfileScreen},
Contact: { screen: MemberContactScreen},
Reward: { screen: MemberRewardScreen},
},{
contentComponent: props => <DrawerScreen {...props} />
});
DrawserScreen.js
const DrawserScreen = props => {
let totalitem = props.items;
return(
<ScrollView style={{backgroundColor:'#000'}}>
<SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
{
totalitem.map((ritem,i)=>{
let txtstyle = null;
if(props.activeItemKey == ritem.key){
txtstyle = styles.draweritemstxt_active;
}else{
txtstyle = styles.draweritemstxt_inactive;
}
return(
<TouchableHighlight key={i} activeOpacity={0.9} onPress={()=> props.navigation.navigate(ritem.key)} style={styles.draweritems}>
<View>
<Text style={txtstyle}>{_convertRouteToTitle(ritem.routeName)}</Text>
</View>
</TouchableHighlight>
);
})
}
</SafeAreaView>
</ScrollView>
);
}
export default DrawserScreen;

React Navigation how to pass props to TabNavigator Stateless Functional Components

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} />
}
}
});

Navigate to different screen from a button in a header

I am using the new React-navigation from react-native. I have the navigation as follows:
StackNavigator:
TabNavigator // HomeNavigation
TabNavigator // NotificationNavigation
Full code:
const MainNavigation = StackNavigator({
Home: {
screen: HomeNavigation,
},
Notification: {
screen: NotificationNavigation,
}
});
const HomeNavigation = TabNavigator({
AllPost: {
screen: All,
},
ArticlePost: {
screen: Article,
},
BusinessPost: {
screen: Job,
},
});
HomeNavigation.navigationOptions = {
title: 'Home',
header: {
right: <SearchNotification/>
},
};
class SearchNotification extends React.Component {
goToNotification = () => {
this.props.navigate('Notification');
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity>
<Icon name="md-search" style={styles.Icon}/>
</TouchableOpacity>
<TouchableOpacity style={styles.notificationWrapper} onPress={this.goToNotification}>
<Icon name="md-notifications" style={styles.Icon}/>
<Text style={styles.number}>3</Text>
</TouchableOpacity>
</View>
)
}
}
const NotificationNavigation = TabNavigator({
Comment: {
screen: NotificationComment,
},
Follow: {
screen: NotificationFollow,
}
});
HomeNavigation has a header, and the header has a right component of SearchNotification. SearchNotification has an icon which on press I would like to go to the NotificatoinNavigation.
However, if I make changes to the header of HomeNavigation to this way, the SearchNotification is not displayed in the header.
HomeNavigation.navigationOptions = {
title: 'Home',
header: {
tintColor: 'white',
style: {
backgroundColor: '#2ec76e',
},
right: ({navigate}) => <SearchNotification navigate={navigate}/>
},
};
How can I navigate to different screen from a button in a header?
So the problem was (I think), inside the navigationOptions instead of using navigations I had to use navigate, and pass it as a props to the child (i.e. the SearchNotification).
So the final code looks like this:
HomeNavigation.navigationOptions = {
title: 'Home',
header: ({navigate}) => ({
right: (
<SearchNotification navigate={navigate}/>
),
}),
};
And within the SearchNotification component:
export default class SearchNotification extends React.Component {
goToNotification = () => {
this.props.navigate('Notification');
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity>
<Icon name="md-search" style={styles.Icon}/>
</TouchableOpacity>
<TouchableOpacity style={styles.notificationWrapper}
onPress={() => this.props.navigate('Notification')}>
<Icon name="md-notifications" style={styles.Icon}/>
<Text style={styles.number}>3</Text>
</TouchableOpacity>
</View>
)
}
}
Code that worked for me:
import Header from '../Containers/Header'
.........................................
navigationOptions: ({ navigation }) => ({
title: 'Find User',
headerRight: <Header navigation={navigation} />,
headerStyle: styles.header
})
And to move to other screen:
this.props.navigation.navigate('UserDetail', {});

Resources