I have a stack navigator structure like this
index.js -> App.js -> LoginStck, HomeNavStack
From LoginStck on successful login I go to HomeNavStack
and from while doing this I reset the stack to have only HomeNavStack(did that to avoid login screen when going back) In HomeStack there are 4 tabs namely Home/Payment/Profile/More with separate stack for each tab. I navigate to MoreScreen within More tab and won logout I need to go to Login Stack(the very first one discarding all other screen).
I did try this`
dothis = async () => {
const someAction = StackActions.reset({
index: 0,
key: null,
actions: [
NavigationActions.navigate({ routeName: 'HomeNavigatorNew'})
]
});
this.props.navigation.navigate(someAction)
}
but didn't work. Any insights....??
Thanks in Advance
`
The recommend way to switch between Login and other screens is by using createSwitchNavigator.
For more information please check:
https://reactnavigation.org/docs/en/switch-navigator.html#docsNav
I created a simple example that can be helpful for your case:
import React from 'react';
import {
View,
Text,
Button,
} from 'react-native';
import {
createStackNavigator,
createBottomTabNavigator,
createSwitchNavigator,
} from 'react-navigation';
class LoginScreen extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>LoginScreen</Text>
<Button
title={'Login'}
onPress={() => this.props.navigation.navigate('HomeStack')}
/>
</View>
)
}
}
class PaymentScreen extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>PaymentScreen</Text>
</View>
)
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>ProfileScreen</Text>
</View>
)
}
}
class MoreScreen extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>MoreScreen</Text>
<Button
title={'Logout'}
onPress={() => this.props.navigation.navigate('LoginStack')}
/>
</View>
)
}
}
const PaymentStack = createStackNavigator(
{
Payment: PaymentScreen,
}
);
const ProfileStack = createStackNavigator(
{
Profile: ProfileScreen,
}
);
const MoreStack = createStackNavigator(
{
More: MoreScreen,
}
);
const HomeStack = createBottomTabNavigator(
{
PaymentStack: PaymentStack,
ProfileStack: ProfileStack,
MoreStack: MoreStack,
}
);
const LoginStack = createStackNavigator(
{
Login: LoginScreen,
}
);
export default createSwitchNavigator(
{
LoginStack: LoginStack,
HomeStack: HomeStack,
}
);
Related
I am struggling a little bit. I have tried to create more components for my React native app but after I did it my ButtonSaving stoped redirecting to Dashboard for some reason. I was trying some ways to pass onRowPress to component but without luck. What do I do incorrectly here please?
Login button is working fine => redirecting to Dashboard
ButtonSaving not working at all => should redirect to Dashboard
AppNavigator.js
import { createStackNavigator } from 'react-navigation-stack'
import { createAppContainer } from 'react-navigation';
import Homepage from './components/Homepage/Homepage';
import Dashboard from './components/Dashboard/Dashboard';
const AppNavigator = createStackNavigator({
Homepage: Homepage,
Dashboard: { screen: Dashboard},
},
{
initialRouteName: 'Homepage',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: 'white',
opacity: 70,
borderBottomColor: 'white',
borderColor: 'white'
},
headerTintColor: 'black',
headerTitleStyle: {
fontWeight: 'bold'
}
}
}
);
const Container = createAppContainer(AppNavigator);
export default Container;
Homepage.js
import React from 'react';
import { StyleSheet, Text, View, Button, Image } from 'react-native';
import {NavigationActions} from 'react-navigation';
// COMPONENTS
import ButtonSaving from './ButtonSaving/ButtonSaving';
class Homepage extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false
},
this.handleClick = this.handleClick.bind(this);
this.onRowPress = this.onRowPress.bind(this);
}
handleClick() {
const counterApp = this.state.counter;
this.setState({
counter: counterApp + 1,
dashboard: 'Dashboard'
})
}
onRowPress = ({ navigation }) => {
this.props.navigation.navigate(this.state.dashboard);
}
render() {
return(
<View style={styles.container}>
{/* LOGIN BUTTON */}
<View style={styles.buttonContainer}>
<View style={styles.buttonLogin}>
<Button title="log in"
color="white"
onPress={() => this.props.navigation.navigate('Dashboard')}/>
</View>
</View>
{/* LOGO CONTAINER */}
<View style={styles.logoContainer}>
<Image
style={{height: 147, width: 170}}
source= {require('./REACT_NATIVE/AwesomeProject/logo.png')}
></Image>
</View>
{/* EXPLAINATION OF WALT */}
<Text style={styles.textContainer}>Lorem ipsum lorem upsum></Text>
{/* Needs to be refactored to VIEW */}
<ButtonSaving onPress={() => this.onRowPress}/>
</View>)
}
ButtonSaving.js
import React from 'react';
import { StyleSheet, Text, View, Button, Image, TouchableOpacity } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
class ButtonSaving extends React.Component {
constructor(props) {
super(props);
this.state = {
},
this.onRowPress = this.onRowPress.bind(this);
}
onRowPress = ({ navigation }) => {
this.props.navigation.navigate(this.state.dashboard);
}
render(){
return(
<View style={styleButton.container}>
<LinearGradient
colors={[
'#00b38f',
'#7dcf5a'
]}
style={styleButton.opacityContainer}>
<TouchableOpacity>
<Button
title="Start Saving"
color='white'
onPress={this.onRowPress}/>
</TouchableOpacity>
</LinearGradient>
</View>
)
}
}
const styleButton = StyleSheet.create({
container: {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
width: '100%',
height: 50,
justifyContent: 'center',
marginTop: '39%'
},
opacityContainer: {
height: 48,
borderRadius: 25,
backgroundColor: 'darkgreen',
width: '70%',
justifyContent: 'center',
alignItems: 'center'
}
})
export default ButtonSaving;
You miss to put dashboard in your state in ButtonSaving.js
In Homepage.js when your are calling handleClick ?. Dunno how you got that working...
You say in the onRowPress this:
this.props.navigation.navigate(this.state.dashboard);
but I don't see anywhere that you set this.state.dashboard.
Probabbly you missed set it up.
It was simple refactor and this helped!
<ButtonSaving navigation ={this.props.navigation}/>
I will update solution for others later.
There is no point to save "dashboard" in the Homepage state or the ButtonSaving state.
In Homepage.js you don't need to pass onPress to ButtonSaving
...
<ButtonSaving navigation={this.props.navigation}/>
...
Next in ButtonSaving.js
onRowPress = () => {
this.props.navigation.navigate('Dashboard');
}
I would like to create a simple navigation example on ReactNative.
Here is a code below;
import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack';
class Home extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home</Text>
<Button
title="To the detail Page"
onPress={() => this.props.navigation.navigate('DetailScreen')}
/>
</View>
);
}
}
class Detail extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Detail Page</Text>
</View>
);
}
}
export default createStackNavigator({
HomeScreen: { screen: Home },
DetailScreen: { screen: Detail },
})
When I code like this, an error is occurred as Line12 this.props.navigation is undefined.
Does anyone have a solution?
Please try the below code :
import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';
import {
createAppContainer
} from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class Home extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home</Text>
<Button
title="To the detail Page"
onPress={() => this.props.navigation.navigate('DetailScreen')}
/>
</View>
);
}
}
class Detail extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Detail Page</Text>
</View>
);
}
}
const APpStack = createStackNavigator({
HomeScreen: { screen: Home },
DetailScreen: { screen: Detail },
})
const App = createAppContainer(APpStack);
export default App;
You can also check the working solution link expo
hope it helps. feel free for doubts
You need a constructor to define properties that are used for storing navigation data (among others):
class Home extends React.Component {
constructor(props) {
super(props);
// ...
}
I am using react-native-overlay-section. The bottom sheet is swipeable to the whole window but I want it to be swipeable to a particular height. How should I do? I have uploaded the code below:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native';
import SlideUp from 'react-native-overlay-section';
export default class App extends Component {
constructor (props) {
super(props);
}
exampleContent = () => {
return (
<View >
<Text>This is test text</Text>
</View>
)
}
render() {
return (
<View style={{flex: 1}}>
<Text>Hello</Text>
<SlideUp
contentSection={this.exampleContent()}
draggableHeight={50}
/>
</View>
)
}
}
Here is the style:
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
I want to build the very simple example shown here: https://reactnavigation.org/docs/tab-based-navigation.html
import React from 'react';
import { Text, View } from 'react-native';
import { TabNavigator } from 'react-navigation'; // 1.0.0-beta.27
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
}
export default TabNavigator({
Home: { screen: HomeScreen },
Settings: { screen: SettingsScreen },
});
How would I go about wrapping the tab navigator in mapStateToProps (or any stack navigator). For example if I want to use dynamic tab names for a specific tab.
Thanks.
const MainRoot =(props) => {
const myTabbar = TabNavigator({
Home: LoginForm,
Settings: RegistrationForm,
third: TabsView
},{
initialRouteName: props.myName
}
);
return <CustomTabNavigator/>;
}
const mapStateToProps = state => ({
myName: state.LibraryMain,
});
export default connect(mapStateToProps)(MainRoot)
I'm trying react navigation inside my react native project. I using TabNavigator for content switching and I would like to make a fixed top bar with my logo inside, each time i swipe to change the tab content, the logo are stick on the top and not moving.
Now i just put the topcontainer inside my HomeScreen
class HomeScreen extends React.Component {
render() {
return(
<View style={styles.container}>
<View style={styles.topcontainer}>
<View style={styles.applogocontainer}>
<Image
source={require('./resources/logo.png')}
style={styles.applogo}
/>
</View>
</View>
</View>
);
}
}
class SecondScreen extends React.Component {
render() {
return(
<View style={styles.container}>
<Text style={styles.whitetext}>Second</Text>
</View>
);
}
}
class ThirdScreen extends React.Component {
render() {
return(
<View style={styles.container}>
<Text style={styles.whitetext}>Third</Text>
</View>
);
}
}
const TabNavs = TabNavigator({
Home: { screen: HomeScreen },
Second: { screen: SecondScreen },
Third: { screen: ThirdScreen },
},{
tabBarPosition:'bottom',
swipeEnabled:true,
tabBarOptions:{
tinColor: '#fff',
activeTintColor: '#eee',
inactiveTintColor: '#fff',
style: {
position: 'absolute',
backgroundColor: 'transparent',
left: 0,
right: 0,
bottom: 0,
},
indicatorStyle:{
backgroundColor:'white'
},
showIcon:true
}
}
);
Yes for topBar menu you can use navigationOptions, is best practise for it:
class MainScreen extends React.Component {
static navigationOptions = () => ({
header: (<YourComponentCustom />),
// others options see you : https://reactnavigation.org/docs/en/headers.html
});
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
// your code
);
}
}
export default MainScreen;
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
class SecondScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
</View>
);
}
}
const RootStack = StackNavigator(
{
Home: {
screen: HomeScreen,
},
SecondScreen: {
screen: SecondScreen,
},
},
{
initialRouteName: 'Home',
navigationOptions: {
header: (
<View style={styles.container}>
<View style={styles.topcontainer}>
<View style={styles.applogocontainer}>
<Image
source={require('./resources/logo.png')}
style={styles.applogo}
/>
</View>
</View>
</View>
)
},
}
);
You can use custom header. See detail from this