How to add mapStateToProps / redux to react-navigation TabNavigator? - javascript

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)

Related

Passing onPress redirect to child component React Native

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

this.props.navigation is undefined (createStackNavigator)

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

Going back from inner screen to parent screen

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

Blank view when i use react-navigation in react-native

I have a problem, when i use TabNavigator on 'react-navigation'. The problem is my screen show the blank view.
this is my code:
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { TabNavigator } from 'react-navigation';
import AuthScreen from './screens/AuthScreen';
import WelcomeScreen from './screens/WelcomeScreen';
export default class App extends React.Component {
render() {
const MainNavigator = TabNavigator({
welcome: { screen: WelcomeScreen },
auth: { screen: AuthScreen }
});
return (
<View style={styles.container}>
<MainNavigator />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
WelcomeScreen.js
import React from 'react';
import { Text, View } from 'react-native';
class WelcomeScreen extends React.Component {
render() {
return (
<View>
<Text>WelcomeScreen</Text>
<Text>WelcomeScreen</Text>
<Text>WelcomeScreen</Text>
<Text>WelcomeScreen</Text>
<Text>WelcomeScreen</Text>
<Text>WelcomeScreen</Text>
</View>
);
}
}
export default WelcomeScreen;
AuthScreen.js
Like
WelcomeScreen.js
I hope you can help me,thanks
Because your styles on App.js. Remove alignItems: "center"
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
},
});

undefined is not an object (evaluating 'this.props.navigation')

I'm trying to create a React Native app with some basic routing.
This is my code so far:
App.js:
import React from 'react'
import { StackNavigator } from 'react-navigation'
import MainScreen from './classes/MainScreen'
const AppNavigator = StackNavigator(
{
Index: {
screen: MainScreen,
},
},
{
initialRouteName: 'Index',
headerMode: 'none'
}
);
export default () => <AppNavigator />
MainScreen.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity, Image } from 'react-native'
import HomeButton from './HomeButton'
export default class MainScreen extends Component {
static navigatorOptions = {
title: 'MyApp'
}
constructor(props) {
super(props)
}
render() {
return (
<View style={styles.container}>
<Image source={require('../img/logo.png')} style={{marginBottom: 20}} />
<HomeButton text='Try me out' classType='first' />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
})
HomeButton.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity } from 'react-native'
import { StackNavigator } from 'react-navigation'
export default class HomeButton extends Component {
constructor(props) {
super(props)
}
render() {
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
}
var Dimensions = require('Dimensions')
var windowWidth = Dimensions.get('window').width;
const baseStyle = StyleSheet.create({
buttons: {
backgroundColor: '#ccc',
borderRadius: 2,
width: windowWidth * 0.8,
height: 50,
shadowOffset: {width: 0, height: 2 },
shadowOpacity: 0.26,
shadowRadius: 5,
shadowColor: '#000000',
marginTop: 5,
marginBottom: 5
},
buttonsText: {
fontSize: 20,
lineHeight: 50,
textAlign: 'center',
color: '#fff'
}
})
const styles = {
first: StyleSheet.create({
style: { backgroundColor: '#4caf50' }
})
}
Everything works fine, but when pressing the button I get
Can't find variable: navigate
I've read that I have to declare it like this:
const { navigate } = this.props.navigation
So I edited HomeButton.js and added that line at the beginning of the render function:
render() {
const { navigate } = this.props.navigation
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
Now I get:
TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')
It seems that the navigation object is not coming into the properties, but I don't understand where should I get it from.
What am I missing here?
React-navigation pass navigation prop to the screen components defined in the stack navigator.
So in your case, MainScreen can access this.props.navigation but HomeButton can't.
It should work if you pass navigation prop from MainScreen to HomeButton :
<HomeButton text='Try me out' classType='first' navigation={this.props.navigation}/>
Edit: You have to define the Homescreen in your stack navigator in order to navigate to it, your onPress={() => navigate('Home')} won't work until then.

Categories