Navigate Between Stack Screens using imported button - javascript

I am new to react native and am having trouble establishing connections between components.
For example
onClickFunction() {this.props.navigation.navigate('CurrencyList')} is not working for my pattern. I did a several research on this subject but I could not understand its logic.
This is my App.js
import React from 'react'
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
// Screens---------------------------------------------------------
// Auth Screens
import Login from './screens/Authentication/Login'
import Register from './screens/Authentication/Register'
// Main Screens
import Home from './screens/Home'
import Converter from './screens/Converter'
import CurrencyList from './screens/CurrencyList'
//-----------------------------------------------------------------
const Stack = createStackNavigator();
var routeName = 'Converter';
export default class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName={`${routeName}`}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Register" component={Register} />
<Stack.Screen name="Converter" component={Converter} />
<Stack.Screen name="CurrencyList" component={CurrencyList} />
</Stack.Navigator>
</NavigationContainer>
)
}
}
This my Converter Page
// Currency Converter Page
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
// Components
import UpdateButton from '../../components/UpdateButton'
import CurrencySelectButton from '../../components/CurrencySelectButton'
import CurrencyTextInput from '../../components/CurrencyTextInput'
import ConvertedCurrencyTextInput from '../../components/ConvertedCurrencyTextInput'
export default function Home() {
return (
<View style={styles.container}>
<View style={styles.textHolder}>
<CurrencyTextInput />
<Text>=</Text>
<ConvertedCurrencyTextInput />
</View>
<View style={styles.buttonHolder}>
<CurrencySelectButton />
<Text>to</Text>
<UpdateButton />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
buttonHolder: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#f1f1f1',
alignContent: 'center'
},
textHolder:{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#f1f1f1',
alignContent: 'center'
}
});
This is the button component that I want to change the screen
import React from 'react'
import { TouchableOpacity, Text, StyleSheet } from 'react-native'
export default class CurrencySelectButton extends React.Component {
onClickFunction() {
this.props.navigation.navigate('CurrencyList')
}
render() {
return (
<TouchableOpacity onPress={() => this.onClickFunction()} style={styles.button} >
<Text style={styles.buttonText} >TRY</Text>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
button: {
backgroundColor: 'black',
padding: 15,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 15,
flex: 1,
height: 75,
marginHorizontal:20
},
buttonText: {
color: 'white',
fontWeight: 'bold',
fontSize: 17
}
})

You will have to pass the navigation prop from home to the button like below
export default function Home({navigation}) {
return (
<View style={styles.container}>
<View style={styles.textHolder}>
<CurrencyTextInput />
<Text>=</Text>
<ConvertedCurrencyTextInput navigation={navigation}/>
</View>
<View style={styles.buttonHolder}>
<CurrencySelectButton />
<Text>to</Text>
<UpdateButton />
</View>
</View>
);
}

Related

React navigation params object empty

When i try passing the params to my review screen it comes up undefined.
I'm using "#react-navigation/native": "^6.1.3" and "#react-navigation/stack": "^6.3.12"
App.js
import 'react-native-gesture-handler';
import { StyleSheet, Text, View, Button, TouchableOpacity, FlatList } from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import Stack from './routes/stack';
export default function App() {
return (
<NavigationContainer>
<Stack/>
</NavigationContainer>
);
}
Stack.js
import {createStackNavigator} from '#react-navigation/stack';
import ReviewScreen from '../screens/Reviews';
import HomeScreen from '../screens/Home';
import AboutScreen from '../screens/About';
const stack = createStackNavigator();
const Stack = () => {
return(
<stack.Navigator>
<stack.Screen name="Home" component={HomeScreen} />
<stack.Screen name="Review" component={ReviewScreen} />
</stack.Navigator>
)}
export default Stack;
HomeScreen
<View style={{width: 100, alignItems: "center"}}>
<TouchableOpacity style={{backgroundColor: "#333", padding: 10, borderRadius: 15, margin: 10}}
onPress={() => navigation.navigate("Review",
{title:"Title Name"}
)}
>
<Text style={{color: "white"}}>{item.title}</Text>
</TouchableOpacity>
</View>
Review.js
import {View, Text, Button} from 'react-native';
import React from 'react';
export default ReviewScreen = ({ navigation, route }) => {
console.log(route);
const { title } = route.params;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Review Screen</Text>
<Button
title="Go to Home"
onPress={() => navigation.goBack()}
/>
</View>
);
};
When I send the object from the home page to the review screen the destructed title throws an undefined error and when I log the route object it shows that the params value is undefined.
console logged route object
{"key": "Review-xxx", "name": "Review", "params": undefined, "path": undefined}
How can I get the params to pass onto the review screen properly?
here is the working code see it!
App.js
import * as React from 'react';
import { Button, View, Text, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details',{ title:"Full Stack Developer"})}
/>
</View>
);
}
function DetailsScreen({ navigation, route }) {
const { title } = route.params;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{title}</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
I had not properly installed the #react-navigation/native and #react-navigation/stack dependencies. Find them stated here and here respectively.

Why Don't I See Anything Rendering in My Stack Navigator?

I have this file and I am unable to see anything, other than the title at the top of screen, rendering:
import React from 'react';
import { Text, View, Button } from 'react-native';
import { NavigationContainer} from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator } from '#react-navigation/stack'
import CreateSessionScreen from '../screens/CreateSessionScreen';
import CompletedSessionsScreen from '../screens/CompletedSessionsScreen';
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
function Hello() {
return (
<View>
<Text
style={{
flex: 1,
fontSize: 100,
height: 80,
width: 80,
borderColor: 'black',
borderWidth: 1,
justifyContent: 'center',
alignItems: 'center'}}>
Hello World
</Text>
<Button title='click me'>Click me</Button>
</View>
);
}
function AppNavigator() {
return (
<NavigationContainer >
<Stack.Navigator>
<Stack.Screen name="Hello" component={Hello} />
<Stack.Screen name="Completed Sessions" component={CompletedSessionsScreen} />
<Stack.Screen name="CreateSessionScreen" component={CreateSessionScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default AppNavigator;
For some reason I can't see anything rendering to the screen. I can throw a console.log in the component to ensure that it is rendering. I have a couple of components imported, and then threw the Hello component in the same file for troubleshooting, and can't get either to render
the problem is with your fontSize = 100 and you have the height/width very smaller compare to that. change it to 10 and see what happens.
function Hello() {
return (
<View
style={{
justifyContent: 'center',
alignItems: 'center',
flex: 1,
}}>
<Text>
Hello World
</Text>
<Button title="click me">Click me</Button>
</View>
);
}

How to Create Top Navigation Tab Under Another Component in React Native?

I'm using react-navigation version 5, currently, I have a screen with Text and Button inside a View which placed at the top of the SafeAreaView, and I need to add TopTabNavigator just below the View.
Here's the code:
TimelineComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';
class TimelineComponent extends React.PureComponent {
render() {
return (
<ScrollView>
<Text>Timeline</Text>
</ScrollView>
);
}
}
export default TimelineComponent;
TrendingComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';
class TrendingComponent extends React.PureComponent {
render() {
return (
<ScrollView>
<Text>Trending</Text>
</ScrollView>
);
}
}
export default TrendingComponent;
TopNav.js
import React from 'react';
import {createMaterialTopTabNavigator} from '#react-navigation/material-top-tabs';
import TimelineComponent from '../TimelineComponent';
import TrendingComponent from '../TrendingComponent';
const Tab = createMaterialTopTabNavigator();
export function TopNav() {
return (
<Tab.Navigator>
<Tab.Screen name="Timeline" component={TimelineComponent} />
<Tab.Screen name="Trending" component={TrendingComponent} />
</Tab.Navigator>
);
}
WallFragmentComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
Keyboard,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {TopNav} from './TopNav';
const styles = StyleSheet.create({
container: {
padding: 20,
},
header_container: {
backgroundColor: 'white',
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
header_text: {
fontSize: 30,
fontWeight: '500',
},
new_chat_button: {
alignItems: 'center',
borderColor: 'blue',
borderWidth: 1,
borderRadius: 12,
display: 'flex',
flexDirection: 'row',
paddingHorizontal: 22,
paddingTop: 6,
paddingVertical: 6,
},
top_nav: {
marginVertical: 20,
},
});
class WallFragmentComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
input: {},
secureTextEntry: true,
};
}
handleInput = (name, value) => {
this.setState({
input: {...this.state.input, [name]: value},
});
};
render() {
return (
<View style={{backgroundColor: 'white'}}>
<SafeAreaView>
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
accessible={false}>
<View style={styles.container}>
<View style={styles.header_container}>
<Text style={styles.header_text}>Wall</Text>
<TouchableOpacity style={styles.new_chat_button}>
<Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
<Text style={{fontWeight: '500', color: 'blue'}}>
New Post
</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
<View style={styles.top_nav}>
<TopNav />
</View>
</SafeAreaView>
</View>
);
}
}
export default WallFragmentComponent;
In the WallFragmentComponent.js file, I have placed <TopNav /> inside a View, but it's not rendering when I run the project. Here's the screenshot:
screenshot
How am I able to add top navigation just under the Wall Text and New Post button? any help will be much appreciated.
Thank you,
Regards
This might help
// TopNav.js
const Tab = createMaterialTopTabNavigator();
const AppNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Timeline" component={TimelineComponent} />
<Tab.Screen name="Trending" component={TrendingComponent} />
</Tab.Navigator>
)
}
export default AppNavigator;
WallFragmentComponent.js
import AppNavigator from './AppNavigator';
...........
const TopNav = createAppContainer(AppNavigator);
class WallFragmentComponent extends React.PureComponent {
......
render() {
return (
<View style={{backgroundColor: 'white'}}>
......
<TopNav />
......
</View>
);
}
}
You can also use react-native-scrollable-tab-view
Well, finally I have found the solution:
Change the first <View ... /> element into <SafeAreaView style={{flex: 1}} /> and then everything is working correctly.
WallFragmentComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
Keyboard,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {TopNav} from './TopNav';
const styles = StyleSheet.create({
container: {
padding: 20,
},
header_container: {
backgroundColor: 'white',
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
header_text: {
fontSize: 30,
fontWeight: '500',
},
new_chat_button: {
alignItems: 'center',
borderColor: 'blue',
borderWidth: 1,
borderRadius: 12,
display: 'flex',
flexDirection: 'row',
paddingStart: 22,
paddingEnd: 22,
paddingTop: 6,
paddingBottom: 6,
},
top_nav: {
marginTop: 20,
},
});
class WallFragmentComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
input: {},
secureTextEntry: true,
};
}
handleInput = (name, value) => {
this.setState({
input: {...this.state.input, [name]: value},
});
};
render() {
return (
<SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View style={styles.header_container}>
<Text style={styles.header_text}>Wall</Text>
<TouchableOpacity style={styles.new_chat_button}>
<Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
<Text style={{fontWeight: '500', color: 'blue'}}>
{' '}
New Post
</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
<TopNav />
</SafeAreaView>
);
}
}
export default WallFragmentComponent;
Screenshot
And that's it

Undefined this.props.navigation when using it in App.js inside Stack Screen component

I need to use navigation when pressing the bag icon in the header. When I press it, I get the following error:
undefined is not an object (evaluating '_this.props.navigation')
The thing is I need to use it inside a Stack.Screen component, but props.navigation always return undefined.
App.js file:
import React, { Component } from 'react';
import {
Button,
Text,
TextInput,
View,
StyleSheet,
TouchableOpacity,
Image,
} from 'react-native';
import { Header } from 'react-navigation-stack';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import TelaInicial from './components/telaInicial';
import TelaCarrinho from './components/telaCarrinho';
const Stack = createStackNavigator();
export default function AppContainer() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Inicial">
<Stack.Screen
name="Inicial"
component={TelaInicial}
options={{
title: '',
headerTintColor: 'white',
headerStyle: { backgroundColor: '#6b39b6', height: 100 },
height: Header.height,
headerLeft: null,
headerTitle: (
<View>
<TouchableOpacity
onPress={() => {
this.props.navigation.navigate('Carrinho');
}}>
<Image
style={{
width: 29,
height: 29,
marginTop: 0,
marginLeft: 170,
}}
source={require('./assets/shopping bag.png')}
/>
</TouchableOpacity>
</View>
),
}}
/>
<Stack.Screen
name="Carrinho"
component={TelaCarrinho}
options={{
title: '',
headerTintColor: 'white',
headerStyle: { backgroundColor: '#6b39b6', height: 100 },
height: Header.height,
headerBackTitle: 'Voltar',
headerTitle: 'Carrinho'.toUpperCase(),
headerTitleStyle: {
fontSize: 17,
fontWeight: 600,
},
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
Do you guys have any idea how I can fix it?
I have a link to Expo: https://snack.expo.io/#rapolasls/eager-crackers
Thank you!
Per React Navigation v5 documentation on createStackNavigator, the header property can be either an object or function.
We use it as a function below to gain access to navigation property. 👍
import React from "react";
import { View, Text, TouchableOpacity, } from "react-native";
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const Stack = createStackNavigator();
const Placeholder = (props) => {
const {
name,
backgroundColor,
} = props;
return (
<View style={{ flex: 1, backgroundColor, justifyContent: "center", alignItems: "center", }}>
<Text style={{ fontSize: 20, color: "white", }}>{ name }</Text>
</View>
)
}
const ScreenA = (props) => {
return <Placeholder name="Screen A" backgroundColor="steelblue" />
}
const ScreenB = (props) => {
return <Placeholder name="Screen B" backgroundColor="tomato" />
}
const RootNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen component={ScreenA} name="a" options={({ navigation }) => {
// navigation object available
const navigateToB = () => { navigation.navigate("b") };
return {
headerTitle: () => {
return (
<TouchableOpacity onPress={navigateToB} style={{ backgroundColor: "green", justifyContent: "flex-end", alignItems: "center", }}>
<Text style={{ fontSize: 20, color: "white", }}>{ "Screen A" }</Text>
</TouchableOpacity>
)
}
}
}} />
<Stack.Screen component={ScreenB} name="b" options={{ headerTitle: "Screen B" }} />
</Stack.Navigator>
);
}
export default function() {
return (
<NavigationContainer>
<RootNavigator />
</NavigationContainer>
);
}

Navigating between screens having two separate react native files

I am new to react native and I want to navigate between screens. I have two sample files
#App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Home from './src/Home';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Home/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFEB3B',
alignItems: 'center',
justifyContent: 'center',
},
});
and another file
#Home.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity} from 'react-native';
export default class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>User</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>Contractor</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
buttonText: {
fontSize:16,
fontWeight:'500',
color:'#212121',
textAlign:'center'
},
button: {
width:300,
borderRadius: 25,
backgroundColor:'#FCE4EC',
marginVertical: 10,
paddingVertical:16
}
});
How do I make it that when either User or Contractor are clicked in Home.js file they take me to different screens preferably using stacknavigator. I tried the documentation but can't seem to figure out the way forward.
You could do this easily using StackNavigator offered by react-navigation library.
Here is the idea:
In the App.js file you have to refer to the stacknavigator/parent of your navigation.
#App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { StackNavigator } from 'react-navigation';
import Home from './src/Home';
import Contractor from './src/Contractor';
import User from './src/User';
const Main = StackNavigator({
HomeScreen: {
screen: Home
},
UserScreen: {
screen: User,
},
ContractorScreen: {
screen: Contractor,
},
}
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Main/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFEB3B',
alignItems: 'center',
justifyContent: 'center',
},
});
Home file:
#Home.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity} from 'react-native';
export default class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button}
onPress={() => this.props.navigation.navigate({ routeName: 'UserScreen'})}>
<Text style={styles.buttonText}>User</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}
onPress={() => this.props.navigation.navigate({ routeName: 'ContractorScreen'})}>
<Text style={styles.buttonText}>Contractor</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
buttonText: {
fontSize:16,
fontWeight:'500',
color:'#212121',
textAlign:'center'
},
button: {
width:300,
borderRadius: 25,
backgroundColor:'#FCE4EC',
marginVertical: 10,
paddingVertical:16
}
});
User file:
#User.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity} from 'react-native';
export default class User extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>I am the User screen</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize:16,
fontWeight:'500',
color:'#212121',
textAlign:'center'
});
And finally, Contractor file:
#Contractor.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity} from 'react-native';
export default class Contractor extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>I am the Contractor screen</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize:16,
fontWeight:'500',
color:'#212121',
textAlign:'center'
});

Categories