React Native Stack Navigation Params - javascript

I'm trying to use params on the header of my Image details screen!
Here's a brief explanation.
My user enters an input, I call an api and display the info on the screen:
Home.js
<View style={styles.viewpic}>
<TouchableOpacity onPress={() => navigation.navigate('ImageDetails',
item)}>
<Image
style={{
height: 104,
}}
source={{uri:item.url}}/>
</TouchableOpacity>
</View>
Then, the user clicks on the chosen data, displayed on the screen, and my app navigates to the details page:
ImageDetails.js
export default function ImageDetails({navigation}) {
return(
<ScrollView>
<View>
<Image
source={{uri:navigation.getParam('url')}}/>
<View style={styles.descriptionBox}>
<Text style={styles.imageDet}>Description:{" "}
{navigation.getParam('explanation')}</Text>
</View>
</View>
</ScrollView>
this is the navigation folder I have:
homeStack.js
const screens = {
Home: {
screen: Home,
navigationOptions:{ headerShown: false}
},
ImageDetails: {
screen: ImageDetails,
navigationOptions: () => {
return{
headerTitle: () => <Header/>,
}
}
}
}
const HomeStack = createStackNavigator(screens);
export default createAppContainer(HomeStack);
plus the HEADER component that I'm trying to use in the header navigation (top of the screen):
Header.js
export default function Header({navigation}) {
return(
<View style={styles.descriptionBox}>
<Text style={styles.imageDet}>Params here!</Text>
</View>
)
Here is what the Image detail screen looks like:
My goal is:
to be able to use the data params on the header.
I tried a few different combos but I keep on getting the error: "cant read params"
Some of the things I tried:
Header.js :
export default function Header({navigation}) {
return(
<View style={styles.descriptionBox}>
<Text style={styles.imageDet}>Test:{navigation.getParam('item')}
</Text>
</View>
)
Homestack component:
homeStack.js
const screens = {
Home: {
screen: Home,
navigationOptions:{ headerShown: false}
},
ImageDetails: {
screen: ImageDetails,
navigationOptions: ({navigation}) => {
return{
headerTitle: () => <Header navigation=
{navigation.getParams('title')}/>,
}
}
}
}
const HomeStack = createStackNavigator(screens);
export default createAppContainer(HomeStack);
I also have read the documentation but I'm not sure how I would insert the "Navigation.push" with params here.
Thanks for your help!

try using the existent image details page instead of creating
a new one!
ImageDetails: {
screen: ImageDetails,
navigationOptions: ({navigation}) => {
return{
headerTitle: () => {
return(
<View>
<Text>{navigation.getParam('title')}
</Text>
</View>
)
},

Related

React native - No Icons on bottom menu

I'm trying to create a bottom menù flow, but I don't understand how and where I need to set the Icons of the bottom menù
At the moment I have setted the menù, it works and I'm able to personalize the menù names, but not able to set the icons. I start with the navigationOptions and before I changed the class in an extention of a component it works.
The following code is in my App.js File
const switchNavigator = createSwitchNavigator({
loginFlow: createStackNavigator({
Signin: SigninScreen,
Signup: SignupScreen
}),
mainFlow: createBottomTabNavigator({
/*Spogliatoio: createStackNavigator({
Game: GameScreen,
}),*/
Rosa: createStackNavigator({
Team: TeamScreen,
PlayerDetail: PlayerDetailScreen,
}),
Classifica: createStackNavigator({
LeagueTable: LeagueTableScreen,
}),
Calendario: createStackNavigator({
LeagueCalendar: LeagueCalendarScreen,
}),
/*Carriera: createStackNavigator({
Trainer: TrainerScreen,
}),*/
}),
});
const App = createAppContainer(switchNavigator);
export default () => {
return (
<AuthProvider>
<App ref={(navigator) => {setNavigator(navigator)}}/>
</AuthProvider>
);
};
And one of the class of my menu view is the following
export default class LeagueTableScreen extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
nomeSquadra:''
}
}
componentDidMount() {
this.fetchData()
.catch((error) => {
//console.log(`Error: ${error}`)
});
}
render() {
const { state, navigate } = this.props.navigation;
const teamName = this.state.nomeSquadra;
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator/>
</View>
)
} else {
return (
<>
<SafeAreaView style={styles.container}>
<View style={styles.listItem}>
<Text style={styles.itemTeamName}>Nome Squadra</Text>
<Text style={styles.itemLegueDetail}>PG</Text>
<Text style={styles.itemLegueDetail}>V</Text>
<Text style={styles.itemLegueDetail}>P</Text>
<Text style={styles.itemLegueDetail}>S</Text>
<Text style={styles.itemLegueDetail}>+/-</Text>
<Text style={styles.itemLegueDetail}>RF</Text>
<Text style={styles.itemLegueDetail}>RS</Text>
<Text style={styles.itemLegueDetail}>PT</Text>
</View>
<FlatList style={styles.flatl}
data={this.state.dataSource}
keyExtractor={(item) => item.idSquadra}
renderItem={({item}) => {
return(
<TouchableOpacity >
<LegueViewItem item={item} nomeSquadra={teamName}/>
</TouchableOpacity>
)
}}
/>
</SafeAreaView>
</>
)
}
}
}
LeagueTableScreen['navigationOptions'] = () => ({
title: 'Classifica',
tabBarIcon: <SimpleLineIcons name="people" size={18} />
})
Can someone help me to set the icons on the bottom menu?
Thank you a lot in advance!
I finally found the answer ^^
createStackNavigator gives you a stackConfig option and there you can implement your NavigationOprions. So I only need to define my createStackNavigator with the following structure
Rosa: createStackNavigator({
Team: TeamScreen,
PlayerDetail: PlayerDetailScreen,
}, {navigationOptions: {tabBarIcon: <SimpleLineIcons name="people" size={18} />}
}),
I hope this can help some new developer that are experimenting React-Native :D

Why is React Native App.js navigation undefined in App.js?

export default function App ({navigation})
There is a function that starts with and contains <Stack.Navigator>.
But when I want to use the navigation feature and use "navigation.navigate ('Lead') in onPress
TypeError: undefined is not an object evaluating react navigation
I get an error. My English is not very good. Please help me on this topic. Now I'm adding the sample codes to you.
import * as React from 'react';
import { StyleSheet, AsyncStorage, Alert, View, Image, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { ApplicationProvider, Layout, Input, Button, Text, Spinner, IconRegistry, Icon } from '#ui-kitten/components';
import { EvaIconsPack } from '#ui-kitten/eva-icons';
import * as eva from '#eva-design/eva';
import LinkingConfiguration from './navigation/LinkingConfiguration';
import * as axios from 'axios';
import Base64 from './components/Base64';
import LeadScreen from './screens/LeadScreen';
import AddLeadScreen from './screens/AddLeadScreen';
import TabBarIcon from './components/TabBarIcon';
import HomeScreen from './screens/HomeScreen';
import CampaignsScreen from './screens/CampaignsScreen';
import MenuScreen from './screens/MenuScreen';
const Stack = createStackNavigator();
export default function App({ navigation }) {
const logout = async () => {
await AsyncStorage.removeItem('token');
dispatch({ type: 'SIGN_OUT' });
};
return (
<>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={eva.light}>
<Layout style={styles.container}>
<AuthContext.Provider value={authContext}>
<NavigationContainer linking={LinkingConfiguration}>
<Stack.Navigator>
{state.isLoading ? (
// We haven't finished checking for the token yet
<Stack.Screen name="Splash" component={SplashScreen} options={{ headerShown: false }} />
) : state.token == null ? (
// No token found, user isn't signed in
<>
<Stack.Screen name="Login" component={LoginScreen} options={{ title: 'Oturum Açın' }} />
</>
) : (
// User is signed in
<>
<Stack.Screen name="User" component={UserScreen} options={{
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4} underlayColor='transparent' onPress={() => logout() } style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='power-outline'
/>
</TouchableOpacity>
)
}} />
<Stack.Screen name="Lead" component={LeadScreen} options={{
title: 'Müşteri Adayları',
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { fontWeight: 'bold', color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4} underlayColor='transparent' onPress={ () => console.log(navigation) } style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='plus-outline'
/>
</TouchableOpacity>
)}} />
<Stack.Screen name="AddLead" component={AddLeadScreen} options={{ title: 'Müşteri Adayı Ekle' }} />
</>
)}
</Stack.Navigator>
</NavigationContainer>
</AuthContext.Provider>
</Layout>
</ApplicationProvider>
</>
);
}
You can pass the navigation or rout prop into options in the stack.screen like this
options={({navigation})=>({
'Your code here'
})}
I have edited it with your code for you.
<Stack.Screen name="Lead" component={LeadScreen}
options={({ navigation }) => ({
title: 'Müşteri Adayları',
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { fontWeight: 'bold', color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4}
underlayColor='transparent' onPress={() =>
console.log(navigation)} style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='plus-outline'
/>
</TouchableOpacity>
)
})} />
First, I think the navigation here is unnecessary, you can remove it.
export default function App({ navigation }) {
In your screen components, ie. UserScreen, you can use navigation like so
function UserScreen({navigation}) {
// ...some codes
navigation.navigate('WHERE_TO_GO');
// ...some other codes
}
You could also use navigation without passing it to the props.
First you need to import useNavigation
import { useNavigation } from '#'react-navigation/native'
And then, in your component
function UserScreen() {
const nav = useNavigation();
// ...some codes
nav.navigate('WHERE_TO_GO');
// ...some other codes
}
You could get more details here https://reactnavigation.org/docs/use-navigation/
For the onPress function of Lead screen,
<Stack.Screen name="Lead" component={LeadScreen} options={({ navigation }) => ({
title: 'Müşteri Adayları',
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { fontWeight: 'bold', color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4} underlayColor='transparent' onPress={ () => navigation.navigate('WHERE_TO_GO') } style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='plus-outline'
/>
</TouchableOpacity>
)})} />
You should use useLinkProps to solve this issue:
import { useLinkProps } from '#react-navigation/stack';
And this is an example on how to write code which uses it:
const LinkButton = ({ to, action, children, ...rest }) => {
const { onPress, ...props } = useLinkProps({ to, action });
I have tried everything but this worked for me.
Make a function in your app.js and pass props then access using props.navigation like below.
function CustomDrawerContent**(props)** {
.....
logOut = () => {
AsyncStorage.clear();
**props.navigation.navigate("Login");**
};
.....
}

How to get params in other App Container - React Navigation?

I want to use the params I passed to Profile Screen and he is in a separate App Container,
And I create TopTabs and put it in a specific AppContainer because I don't have any way to use it in a one AppContainer so how I Get these Params from another AppContainer?
So My Code here's
First thing, now I'm in the Map Screen and want to navigate to profile screen and pass some params like this
this.props.navigation.navigate('ProviderProfile', {
providerId: marker.id,
providerName: marker.name,
providerService: marker.service,
gKey: marker.gKey,
token: marker.token._55,
region: region
}
And here is Profile Screen, Contain let's say Card and TobTabs "I wrap it in a separate AppContainer"
and want to use params I passed in these TopTabs "every single tab" so how to handle these OR pass these params to every single Tab?
ProviderProfile.js
import React, { Component } from "react";
import Icon from "react-native-vector-icons/Ionicons";
import firebase from "react-native-firebase";
import { createAppContainer } from "react-navigation";
import { NavTabs } from "./ProviderTabs/NabTabs";
import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";
console.disableYellowBox = true;
class ProviderProfile extends Component {
static navigationOptions = ({ navigation }) => {
const { state } = navigation;
return {
title: ` ${state.params.providerName}` || "profile"
};
};
constructor(props) {
super(props);
this.state = {
providerId: this.props.navigation.getParam("providerId"),
providerService: this.props.navigation.getParam("providerService"),
providerName: this.props.navigation.getParam("providerName"),
gKey: this.props.navigation.getParam("gKey"),
token: this.props.navigation.getParam("token"),
region: this.props.navigation.getParam("region"),
fav: false
};
}
_addToFavorite = () => {
const { providerName, providerService, providerId, fav } = this.state;
const currentUser = firebase.auth().currentUser.uid;
this.setState({ fav: !fav });
const ref = firebase
.database()
.ref(`favorites/${currentUser}/${providerId}`);
if (!fav) {
ref
.set({
ProviderId: providerId,
providerName: providerName,
providerService: providerService
})
.then(() => alert("Great, Added to your favorite list"));
} else {
ref.remove();
}
};
render() {
const {
providerName,
providerService,
providerId,
fav,
gKey,
region,
token
} = this.state;
return (
<View style={styles.container}>
{/* <Text>{gKey}</Text> */}
<Image
resizeMode="contain"
source={require("../assets/marker.png")}
/>
<View>
<View>
<Icon
name={`ios-heart${fav ? "" : "-empty"}`}
size={35}
color="#f00"
onPress={this._addToFavorite}
/>
</View>
<Text>
<Icon name="ios-star" size={20} color="#f2ba13" />
<Icon name="ios-star" size={20} color="#f2ba13" />
<Icon name="ios-star" size={20} color="#f2ba13" />
<Icon name="ios-star-half" size={20} color="#f2ba13" />
<Icon name="ios-star-outline" size={20} color="#f2ba13" />
</Text>
<Text style={{ fontSize: 19, color: "#000", padding: 5 }}>
{providerName}
</Text>
<Text>
Service: <Text>{providerService}</Text>
</Text>
<View style={{ flexDirection: "row", marginTop: 10 }}>
<TouchableOpacity
onPress={() => alert("Message")}
>
<Text>
Message
</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() =>
this.props.navigation.navigate("Order", {
providerName,
providerId,
providerService,
gKey,
token,
region
})
}
>
<Text
>
Send Order
</Text>
</TouchableOpacity>
</View>
</View>
<Roots /> // Here's Tabs
</View>
);
}
}
const Roots = createAppContainer(NavTabs);
export default ProviderProfile;
And Here is a Tabs Screen "NavTabs"
import {
createMaterialTopTabNavigator,
} from "react-navigation";
import AboutScreen from "./About";
import GalaryScreen from "./Galary";
import ReviewsScreen from "./Reviews";
export const NavTabs = createMaterialTopTabNavigator(
{
About: { screen: AboutScreen },
Galaty: { screen: GalaryScreen },
Reviews: { screen: ReviewsScreen }
},
{
tabBarOptions: {
activeTintColor: "#fff",
inactiveTintColor: "#ddd",
tabStyle: {
justifyContent: "center"
},
indicatorStyle: {
backgroundColor: "#fcc11e"
},
style: {
backgroundColor: "#347ed8"
}
}
}
);
As you see, I want to use the username in Tab "About"
or other Tabs
Send params:
this.props.navigation.navigate('RouteName', { /* params go here */ })
Get params:
this.props.navigation.getParam(paramName, defaultValue)
Example:
this.props.navigation.navigate('NameListScreen', { names:["John","Mary"] })
let params = this.props.navigation.getParam(names, [])
I haven't use React Navigation myself but in their documentation say you can pass props to App Containers, so as you have defined the state with the props from the MapScreen you should probably pass them as props where you have defined your NavTabs Component as <Roots />
Also, there is another alternative to want to achieve as they present in here and it will be done in a redux way.

React-native: undefined is not an object (evaluating '_this.props.navigation.navigate') onpress

const AppStackLog = createDrawerNavigator(
{
Login: {
screen: LogintStack,
navigationOptions: (navOpt) => ({
drawerLabel: ({focused}) =>(
<TouchableOpacity style={[styles.button]} onPress={() => this.navigation.navigate('App')}>
<Text><Icon
size={17}
name="log-in"
family="Galio"
color={focused ? 'white' : materialTheme.COLORS.MUTED} />
<Text size={18}> Logout</Text></Text>
</TouchableOpacity>
),
}),
},
},
Menu
);
export default createSwitchNavigator(
{
App: AppStack,
Home: HomeStack,
Auth:AppStackLog,
},
{
initialRouteName: 'App',
}
);
this is not going to point to some particular component, it's going to point to whatever this was equal to when this code was defined. Instead, the navOpt parameter has what you need on it:
<TouchableOpacity style={[styles.button]} onPress={() => navOpt.navigation.navigate('App')}>

align navscreen content in react-native

I am very new to react-native. I am trying to create a drawer using react-navigation. I could use DrawerNavigator but could not show the header/navbar on all the screens. That is why i create a NavScreen component with profile icon, title and back icon. However they are not aligned properly. I need profile icon to be shown on the left side, title on the center and back button on the right side. How can i do this?
Here is my code
const styles = StyleSheet.create({
container: {
marginTop: Platform.OS === 'ios' ? 20 : 10,
},
});
const NavScreen = ({ navigation, banner }) => (
<ScrollView style={styles.container}>
<Text>{banner}</Text>
<Icon
name="ios-contact-outline"
size={30}
color="#000"
onPress={() => navigation.navigate('DrawerOpen')}
/>
<Icon
name="ios-arrow-round-back-outline"
size={30}
color="#000"
onPress={() => navigation.goBack(null)}
/>
</ScrollView>
);
export default NavScreen;
class App extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.routeName}`,
drawerTitle: `${navigation.state.routeName}`,
drawerLabel: 'Home',
drawerIcon: ({ whiteColor }) => (
<MaterialIcons name="drafts" size={14} style={{ color: whiteColor }} />
),
})
render() {
const { navigation } = this.props;
return (
<ScrollView>
<NavScreen navigation={navigation} banner={'Main'} />
<Text>Main Screen</Text>
</ScrollView>
);
}
}
export default App;
I need similar to the below image
First, try to build a StackNavigation, at headerRight, and headerLeft you define your custom buttons (the above), now you can very easy customize the align/padding whatever you need with your icons/buttons.
const stackNavigatorConfiguration = {
// set first Screen
initialRouteName: 'Home',
mode: Platform.OS === 'ios' ? 'card' : 'card',
navigationOptions: ({navigation}) => ({
headerRight: <DrawerButton navigation={navigation} />,
headerLeft: <YourProfileButton navigation={navigation} />,
headerBackTitle: null
})
}
const YourProfileButton = ({ navigation }) => (
<TouchableOpacity>
<Ionicons
style={styles.profileButton}
name='ios-menu-outline'
size={32}
onPress={() => navigation.goBack(null)}
/>
</TouchableOpacity>
)
const DrawerButton = ({ navigation }) => (
<TouchableOpacity>
<Ionicons
style={styles.drawerIcon}
name='ios-menu-outline'
size={32}
onPress={() => navigation.navigate('DrawerOpen')}
/>
</TouchableOpacity>
)

Categories

Resources