I am getting the below issue when I started to configure with Redux sagas in React native application:
App.js:
import React from 'react';
import AppNavigator from './config/AppNavigator'
import { Provider as PaperProvider } from 'react-native-paper';
import * as Font from 'expo-font'
import { createStore } from 'redux'
import { Provider as ReduxProvider} from 'react-redux'
import InitialReducer from './reducer/Initial-reducer'
const store = createStore(InitialReducer)
export default class App extends React.Component {
componentDidMount() {
Font.loadAsync({
'RobotoBlack': require('./assets/fonts/Roboto/Roboto-Black.ttf'),
'RobotoBold': require('./assets/fonts/Roboto/Roboto-Bold.ttf'),
'RobotoRegular': require('./assets/fonts/Roboto/Roboto-Regular.ttf'),
});
}
render() {
return (
<ReduxProvider store={store}>
<PaperProvider>
<AppNavigator />
</PaperProvider>
</ReduxProvider>
);
}
}
AppNavigator.js
import { createStackNavigator, createAppContainer } from 'react-navigation';
import Home from './../pages/Home';
import InitialDetails from '../pages/LandingPage/initialDetails';
const AppNavigator = createStackNavigator({
Home: {
screen: Home,
navigationOptions: {
header: null,
}
},
InitialDetails: {
screen: InitialDetails,
}
},
{
initialRouteName: 'Home',
});
export default createAppContainer(AppNavigator);
Action
export const USER_INITIAL_INPUT = 'USER_INITIAL_INPUT'
export function updateUserInitialInput (action){
return{
type:USER_INITIAL_INPUT,
action
}
}
Reducer:
import USER_INITIAL_INPUT from './../action/Initial-action'
const initialState = {
userInitalInputFromUser :{
animal : 'tige'
}
}
const InitialReducer = (state = initialState,action) => {
switch(action.type){
case 'USER_INITIAL_INPUT':
return{
...state,
userInitalInputFromUser : action.action
}
default:
return state
}
}
export default InitialReducer
Page where am connecting the Redux.
import React from 'react';
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import {
View,
Text,
ScrollView,
Image,
StatusBar,
StyleSheet,
TouchableOpacity
} from 'react-native';
import {Button } from 'react-native-paper';
// actions
import updateUserInitialInput from './../../action/Initial-action'
import { CommonCSS, initialPageCSS } from '../../Style'
class InitialDetails extends React.Component {
constructor(props) {
super(props)
this.state = {
cookingSkill: 'Beginner',
isVegeterian:false
}
}
static navigationOptions = {
title: "Personalization",
headerStyle: {
backgroundColor: "#fa7776"
},
headerTintColor: "#fff",
headerTitleStyle: {
fontWeight: "bold"
}
};
userInitalInput(whichState,value){
whichState ==='cookingSkill' ?
this.setState({cookingSkill:value}) :
this.setState({isVegeterian:value})
}
render() {
return(
<ScrollView style={CommonCSS.flexContainer}>
<StatusBar backgroundColor="#fa6767" barStyle="light-content" />
{/* Rate your cooking skills */}
<View >
<Text style={initialPageCSS.heading}>Rate your cooking skills!</Text>
</View>
<TouchableOpacity
onPress={this.userInitalInput.bind(this,'cookingSkill','Beginner')}
style={
[initialPageCSS.buttons,
this.state.cookingSkill==='Beginner' ? initialPageCSS.acitveButton : null]
}
activeOpacity={0.5}>
<Image source={require('../../assets/images/avatar.png')} style={initialPageCSS.ImageIconStyle}/>
<Text style={initialPageCSS.TextStyle}> Iam a Beginner </Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.userInitalInput.bind(this,'cookingSkill','Expert')}
style={
[initialPageCSS.buttons,
this.state.cookingSkill==='Expert' ? initialPageCSS.acitveButton : null]
}
activeOpacity={0.5}>
<Image source={require('../../assets/images/avatar.png')} style={initialPageCSS.ImageIconStyle}/>
<Text style={initialPageCSS.TextStyle}> Iam an Expert </Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.userInitalInput.bind(this,'cookingSkill','Professional')}
style={
[initialPageCSS.buttons,
this.state.cookingSkill==='Professional' ? initialPageCSS.acitveButton : null]
}
activeOpacity={0.5}>
<Image source={require('../../assets/images/avatar.png')} style={initialPageCSS.ImageIconStyle}/>
<Text style={initialPageCSS.TextStyle}> Iam a Professional </Text>
</TouchableOpacity>
{/* Rate your cooking skills */}
{/* Are you Vegetarian */}
<View>
<Text style={initialPageCSS.heading}>Are you a Vegetarian!</Text>
</View>
<TouchableOpacity
onPress={this.userInitalInput.bind(this,'isVeg',false)}
style={
[initialPageCSS.buttons,
this.state.isVegeterian ? null : initialPageCSS.acitveButton]
}
activeOpacity={0.5}>
<Image source={require('../../assets/images/avatar.png')} style={initialPageCSS.ImageIconStyle}/>
<Text style={initialPageCSS.TextStyle}> Nope, Show me all Recipes </Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.userInitalInput.bind(this,'isVeg',true)}
style={
[initialPageCSS.buttons,
this.state.isVegeterian ? initialPageCSS.acitveButton : null]
}
activeOpacity={0.5}>
<Image source={require('../../assets/images/avatar.png')} style={initialPageCSS.ImageIconStyle}/>
<Text style={initialPageCSS.TextStyle}> Yes, Hide recipes with meat</Text>
</TouchableOpacity>
<View style = {initialPageCSS.getStartedBtnWrapper}>
<Button
mode="contained"
theme={{
roundness: 5,
width: '90%',
dark: true,
colors: {
primary: '#ec4242',
accent: "#ffffff",
}
}}
contentStyle = {{height:50}}
onPress = {this.props.updateUserInitialInput(this.state)}
>
Get Started
</Button>
</View>
{/* Are you Vegetarian */}
</ScrollView>
);
}
}
InitialDetails.propTypes = {
updateUserInitialInput: PropTypes.func,
userInput : PropTypes.object
}
function mapStateToProps (state) {
alert(JSON.stringify(state))
return{
userInput : state
}
}
// const mapStateToProps = state => ( {
// return{
// userInput : state.userInitalInputFromUser
// }
// } )
const mapDispatchToProps = dispatch => ({
updateUserInitialInput: (userInput) =>
dispatch(updateUserInitialInput(userInput)),
})
export default connect(mapStateToProps, mapDispatchToProps)(InitialDetails)
For now I am not connected with Redux-saga, I am not sure why it throws such an issue in the application. The same approach seems to be working fine in a React application. Can anyone help me fix this issue please?
Related
I'm writing a react-native app via expo and trying to implement redux. I'm not sure if I'm going about this completely the wrong way. I have a home page that has two sections, a search text box and an area with links to content pages. The content pages also contain the same search box component. I want to be able to pass the contents of the search box input to the content page so that the user doesn't need to enter this again (and will probably require access to this content further in the user journey)
My app.js looks like the below:
import React from 'react';
import 'react-native-gesture-handler';
import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import ContentPage from './pages/ContentPage.js';
import LogoTitle from './components/LogoTitle';
import EventsListPage from './pages/EventsListPage.js';
import EventPage from './pages/EventPage';
import VenuePage from './pages/VenuePage';
import HomeScreen from './pages/HomePage';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
const initialState ={
postcode:"abcefg"
}
const reducer = (state = initialState, action) => {
switch(action.type)
{
case 'SET_POSTCODE':
return {
postcode: action.text
}
default:
console.log("returning default state")
return state
}
}
const store = createStore(reducer);
const RootStack = createStackNavigator(
{
Home: HomeScreen,
ContentPage: ContentPage,
EventsListPage: EventsListPage,
EventPage: EventPage,
VenuePage: VenuePage
},
{
initialRouteName: 'Home',
defaultNavigationOptions: {
headerTitle: () => <LogoTitle />,
headerLeft: () => null,
headerStyle: {
backgroundColor: '#ADD8E6'
}
},
}
);
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
<AppContainer />
</Provider>);
}
}
Homepage.js:
import React from 'react';
import { StyleSheet, View } from 'react-native';
import SearchBox from '../components/SearchBox'
import TypeDrillDownArea from '../components/TypeDrillDownArea'
import 'react-native-gesture-handler';
class HomeScreen extends React.Component {
constructor(props) {
super(props);
state = {
};
}
render() {
return (
<View style={styles.container}>
<SearchBox navigation={this.props.navigation} eventTypeId=''/>
<TypeDrillDownArea navigation={this.props.navigation} />
</View>
);
}
}
export default HomeScreen
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'stretch'
},
});
Relevant searchbox.js:
render() {
return (
<ImageBackground source={topperBackground} style={{width: '100%'}}>
<View>
<View style={styles.row}>
<View>
<TextInput
value={this.props.postcode}
autoCapitalize="characters"
style={styles.inputBox}
placeholder="Enter Postcode"
onChangeText={(e) => this.props.setPostcode(e)}
/>
</View>
<View>
<TouchableOpacity
disabled={this.state.locationDisabled}
onPress={() => {
this.props.navigation.navigate('EventsListPage', {
navigation: this.props.navigation,
eventTypeId: this.state.eventTypeId,
locLongitude: this.state.location.coords.longitude,
locLatitude: this.state.location.coords.latitude,
});
}}>
<Image
style={styles.locationPin}
source={locationPin}
/>
</TouchableOpacity>
</View>
</View>
<View style={styles.searchButtonArea}>
<TouchableOpacity
onPress={() => {
console.log("postcode is: " + this.state.postcode)
this.props.navigation.navigate('EventsListPage', {
eventTypeId: this.state.eventTypeId,
postcode: this.props.postcode,
});
}}>
<Text style={styles.searchButton}>SEARCH</Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SearchBox)
function mapStateToProps(state){
return {
postcode:state.postcode
}
}
function mapDispatchToProps(dispatch){
return{
setPostcode : (e) => dispatch({
type: 'SET_POSTCODE',
postcode : e
})
}
}
and finally relevant contentpage.js:
<View style={styles.container}>
<SearchBox navigation={this.props.navigation} eventTypeId={this.state.eventTypeId} />
<Image source={imageType(this.state.dataSource[0].eventTypeId)} style={styles.eventType} />
<Text style={styles.textToDisplay}>
{this.state.dataSource[0].eventTypeDescription}
</Text>
</View>
On load, the box is prepopulated with "abcefg" as expected. Changing the contents hits the reducer as expected. However when I navigate to a content page which loads the search box again the value is empty, regardless if I've changed the original state or not.
Am I missusing redux for what it's intended? Should I be doing this a different way?
For clarity below is the organisation of the components
In the reducer(), you are accessing action.text but in the dispatch(), you passed postcode value to postcode instead of text.
my App.js code
import React from 'react'
import { Icon } from 'react-native-elements'
import { StyleSheet, View, StatusBar } from 'react-native'
import { createAppContainer } from 'react-navigation'
import { createStackNavigator } from 'react-navigation-stack'
import HomeScreen from './screens/homeScreen'
import LoginScreen from './screens/loginScreen'
import SignupScreen from './screens/signup'
import Screen2 from './screens/screen2'
import Screen1 from './screens/screen1'
export default class App extends React.Component {
setLogged(){
this.setState({logged:true})
this.forceUpdate()
}
//change to false when want to enable login feature else true
state = {
logged: false,
}
render() {
if(this.state.logged){
return(
<View style={styles.container} >
<StatusBar hidden = {false}/>
<AppContainer />
</View>
)
}else{
return(
<View style={styles.container} >
<StatusBar hidden = {false}/>
<LoginScreen signup={()=>this.props.navigation.navigate('Signup')} success={()=>this.setLogged()} />
</View>
)
}
}
}
const styles = StyleSheet.create({
container: {
position: 'relative',
width: '100%',
height: '100%',
backgroundColor: '#000000',
},
})
const HomeAppContainer = createStackNavigator(
{
Home: {screen: HomeScreen},
Signup: { screen: SignupScreen },
Screen1: { screen: Screen1 },
Screen2: { screen: Screen2 },
},
{initialRouteName: "Home"},
);
const AppContainer = createAppContainer(HomeAppContainer)
and the login screen contains
import React, { Component } from 'react';
import { StyleSheet, View, Text, TouchableOpacity, TextInput, ToastAndroid } from 'react-native';
import Colors from '../constants/colors'
import GLOBAL from '../constants/global'
export default class LoginScreen extends Component {
state = {
email: '',
password: '',
}
login() {
if (userid == 'admin') {
ToastAndroid.show('Invalid email/password', ToastAndroid.SHORT);
} else {
GLOBAL.userid = userid;
this.props.success()
}
})
}
render() {
return (
<View style={styles.MainContainer}>
<Text style={styles.text}>Email:</Text>
<View style={styles.inputView}>
<TextInput
style={styles.inputs}
autoFocus
returnKeyType="next"
keyboardType="email-address"
onChangeText={(email) => { this.setState({ email: email }) }}
/>
</View>
<Text style={styles.text}>Password:</Text>
<View style={styles.inputView}>
<TextInput
style={styles.inputs}
secureTextEntry
onChangeText={(password) => { this.setState({password:password}) }}
/>
</View>
<View style={styles.buttonGroup}>
<TouchableOpacity
style={styles.button}
onPress={() => { this.login() }} >
<Text style={{ fontSize: 24 }}>Sign in</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => { this.props.signup() }}>
<Text style={{ fontSize:24 }}>Sign up</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
//my styles here
});
the error is as follows
TypeError: undefined is not an object(evaluating '_this2.props.navigation.navigate')
i am learning react-native and making this login screen.
The app will check if the user is already logged in. if not then he will be prompted login screen which will have sign up option.
If the user is already logged in the app will directly go to home screen where screen1 and screen2 is used in stack
Well, the navigation prop is only passed down the navigation tree. Your App component is not a navigation screen like Home/Signup... (it doesn't have a route)... So basically App is not part of a navigator, it's not created using createStackNavigator or the others.
So, in conclusion the navigation prop is not defined.
Basically, how to fix this: LoginScreen should also be a route inside a navigator, therefore the navigation prop will be defined. Your App component should not render anything besides the <AppContainer /> and further logic should be handled in the first screen defined in the routes, which in your case might be the LoginScreen. In there you'll check if the user is logged in or not and navigate accordingly.
There's a great guide on their website on how to accomplish authentication flow: https://reactnavigation.org/docs/en/4.x/auth-flow.html
I'm new to react-native and am trying to use the Redux framework, I've encountered this problem: (The component for route ' ' must be a React component):
Thank you in advance.
Screen Error
Index.js
import React from 'react'
import { Provider } from 'react-redux'
import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';
import Menu from './app/componnts/Menu'
import storeConfig from './app/store/storeConfig'
const store = storeConfig()
const Redux = () => {
return (
<Provider store={store}>
<Menu />
</Provider>
)
}
AppRegistry.registerComponent(appName, () => Redux);
Menu.js
import React, { Component } from 'react'
import {
StyleSheet,
SafeAreaView,
ScrollView,
Dimensions,
View,
Image,
Text
} from 'react-native'
import { createDrawerNavigator, DrawerItems, } from 'react-navigation'
import Login from './Login/Login'
import Viatura from './Viatura/Viatura'
export default class App extends Component {
render() {
return (
<AppDrawerNavigator />
)
}
}
const CustomDrawerComponent = (props) => (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView>
<DrawerItems {...props} />
</ScrollView>
</SafeAreaView>
)
const AppDrawerNavigator = createDrawerNavigator({
Login,
Viatura,
}, {
contentComponent: CustomDrawerComponent,
drawerWidth: 300,
contentOptions: {
activeTintColor: 'orange'
}
})
Login.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { loginStore } from '../../store/actions/user.js';
import { Text, View, ImageBackground, Dimensions, Image, TextInput, TouchableOpacity, Alert } from 'react-native'
import Icon from 'react-native-vector-icons/FontAwesome'
import axios from 'axios'
import { createIconSetFromIcoMoon } from 'react-native-vector-icons'
import { API_MOTORISTAS_LOGIN } from '../../config'
import icoMoonConfig from '../../resources/fonts/selection.json'
import styles from './styles'
import bgImage from '../../images/fundo-vertical-preto.jpg'
import logo from '../../images/logo-tg-v-01.png'
const MyIcon = createIconSetFromIcoMoon(icoMoonConfig, 'icomoon', 'icomoon.ttf');
class Login extends Component {
constructor(props) {
super(props)
this.state = {
user: '',
password: '',
}
this.loginUser = this.loginUser.bind(this)
}
loginUser = () => {
try {
const { user, password } = this.state
this.setState({ error: '', })
axios.post(`${API_MOTORISTAS_LOGIN}`,
{
'param1': this.state.user,
'param2': this.state.password
}, {
"headers": {
'Content-Type': 'application/json',
}
}).then((response) => {
if (response.data.error) {
Alert.alert((response.data.error));
} else {
this.props.onLogin({ ...this.state })
const api_token = response.data.api_token
this.props.navigation.navigate('Viatura', {
api_token: api_token,
})
}
})
.catch((error) => {
console.log("axios error:", error);
});
} catch (err) {
Alert.alert((err))
}
}
static navigationOptions = {
drawerIcon: ({ tintColor }) => (
<MyIcon name="fonte-tg-33" style={{ fontSize: 24, color: tintColor }} />
)
}
render() {
return (
<ImageBackground
source={bgImage}
style={styles.backgroundContainer}>
<View
style={{
height: (Dimensions.get('window').height / 10) * 10,
alignItems: 'center',
justifyContent: 'center',
}}>
<View style={styles.logoContainer}>
<Image source={logo} style={styles.logo} />
</View>
<View style={styles.inputText}>
<View style={styles.iconContainer}>
<MyIcon style={styles.icon} name="fonte-tg-39" size={25} />
</View>
<TextInput
style={styles.input}
placeholder={'User'}
placeholderTextColor={'rgba(0, 0, 0, 0.6)'}
underlineColorAndroid='transparent'
value={this.state.user}
onChangeText={user => this.setState({ user })}
/>
</View>
<View style={styles.inputText}>
<View style={styles.iconContainer}>
<MyIcon style={styles.icon} name="fonte-tg-73" size={25} />
</View>
<TextInput
style={styles.input}
placeholder={'Password'}
secureTextEntry={true}
placeholderTextColor={'rgba(0, 0, 0, 0.6)'}
underlineColorAndroid='transparent'
value={this.state.password}
onChangeText={password => this.setState({ password })}
/>
</View>
<View style={styles.buttonsLogin}>
<TouchableOpacity style={styles.btnSair}>
<Text style={styles.text}> Sair </Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.loginUser} style={styles.btnEntrar}>
<Text style={styles.text}> Entrar </Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
)
}
}
const mapDispatchToProps = dispatch => {
return {
onLogin: user => dispatch(loginStore(user))
}
}
export default connect(null, mapDispatchToProps)(Login);
actionTypes.js
export const USER_LOGGED_IN = 'USER_LOGGED_IN';
export const USER_LOGGED_OUT = 'USER_LOGGED_OUT';
user.js (inside actions folder)
import { USER_LOGGED_IN, USER_LOGGED_OUT } from './actionTypes'
export const login = user => {
return {
type: USER_LOGGED_IN,
payload: user
}
}
export const logout = () => {
return {
type: USER_LOGGED_OUT,
}
}
user.js (inside reducers folder)
import { USER_LOGGED_IN, USER_LOGGED_OUT } from '../actions/actionTypes'
const initalState = {
user: null,
password: null
}
const reducer = (state = initalState, action) => {
switch (action.type) {
case USER_LOGGED_IN:
return {
...state,
user: action.paypload.user,
password: action.paypload.password
}
case USER_LOGGED_OUT:
return {
...state,
user: null,
password: null,
}
default:
return state
}
}
export default reducer
storeConfig.js
import { createStore, combineReducers } from 'redux'
import userReducer from './reducers/user'
const reducers = combineReducers({
user: userReducer,
})
const storeConfig = () => {
return createStore(reducers)
}
export default storeConfig
As I said at the beginning of the post, I'm still a beginner at react-native, so I'm posting several snippets of code so that I can be as clear as possible about how my situation is.
I don't think your screen is properly setting export default.
can you change this code?
import React, { Component } from 'react'
import {
StyleSheet,
SafeAreaView,
ScrollView,
Dimensions,
View,
Image,
Text
} from 'react-native'
import { createDrawerNavigator, DrawerItems, } from 'react-navigation'
import Login from './Login/Login'
import Viatura from './Viatura/Viatura'
export default class App extends Component {
render() {
return (
<AppDrawerNavigator />
)
}
}
const CustomDrawerComponent = (props) => (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView>
<DrawerItems {...props} />
</ScrollView>
</SafeAreaView>
)
const AppDrawerNavigator = createDrawerNavigator(
{
Login : () => <Login />,
Viatura : () => <Viatura />
},
{
contentComponent: CustomDrawerComponent,
drawerWidth: 300,
contentOptions: {
activeTintColor: 'orange'
}
}
)
OR
import { Login } from './Login/Login'
import { Viatura } from './Viatura/Viatura'
...
const AppDrawerNavigator = createDrawerNavigator(
{
Login : { screen: Login },
Viatura : { screen: Viatura }
},
{
contentComponent: CustomDrawerComponent,
drawerWidth: 300,
contentOptions: {
activeTintColor: 'orange'
}
}
)
Try this
const AppDrawerNavigator = createDrawerNavigator({
Login:Login,
Viatura:Login,
}, {
contentComponent: CustomDrawerComponent,
drawerWidth: 300,
contentOptions: {
activeTintColor: 'orange'
}
})
I have defined all my routes/navigations in my root component (App.js) and am trying to access one of those screens (UserScreen) from a child component(LoginScreen) on click of a button.
Here is my App.js
import React from 'react';
import { StyleSheet, Text, View, TextInput, TouchableHighlight, Button } from 'react-native';
import LoginComponent from './components/LoginComponent';
import { StackNavigator } from 'react-navigation';
class MainWelcome extends React.Component {
render() {
return (
<View>
<Text>Welcome Page</Text>
<Button
title="Login"
onPress={() => this.props.navigation.navigate('Login')}
/>
</View>
);
}
}
class LoginScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<LoginComponent />
</View>
);
}
}
class UserScreen extends React.Component {
render() {
return (
<View>
<Text>Details Screen</Text>
</View>
);
}
}
const RootStack = StackNavigator(
{
Register: {
screen: RegisterScreen,
},
Login: {
screen: LoginScreen,
},
UserPage: {
screen: UserScreen,
},
Welcome: {
screen: MainWelcome,
},
},
{
initialRouteName: 'Welcome',
}
);
export default class App extends React.Component {
render() {
return (
<RootStack />
);
}
}
This is my LoginComponent.js
import React from 'react';
import { StyleSheet, Text, View, TouchableHighlight, TextInput, StackNavigator } from 'react-native';
class LoginComponent extends React.Component {
constructor(){
super();
this.state = {
loginusername: '',
loginpassword: '',
isloggedin: false,
loggedinuser: null,
}
}
render() {
return (
<View>
<Text>Please Log In</Text>
<View>
<TextInput
placeholder="USERNAME"
placeholderTextColor = 'black'
onChangeText={(loginusername) => this.setState({loginusername})}
/>
<TextInput
placeholder="Password"
placeholderTextColor = 'black'
onChangeText={(loginpassword) => this.setState({loginpassword})}
/>
<TouchableHighlight onPress={() => {
{this.props.navigation.navigate('UserPage')}
}
}>
<View>
<Text>Login</Text>
</View>
</TouchableHighlight>
</View>
</View>
);
}
}
export default LoginComponent;
Here in LoginComponent.js, I am doing {this.props.navigation.navigate('UserPage')} to redirect to the userscreen on click of a button but it says TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate'). I am not sure what I am doing wrong and if I should be passing something from the App.js to LoginComponent.js.
If you tried to print your LoginComponent's props you would end up with nothing!,
But what if you pass the navigation as prop to your component like this! :
// App.js
class LoginScreen extends React.Component {
...
<LoginComponent navigation={this.props.navigation}/>
...
}
You will end up with functional navigation prop.
Happy user details navigation :)
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
Image,
Button
} from 'react-native';
import Actions from 'react-native-router-flux';
import First from './First';
export default class Home extends Component{
componentWillMount() {
}
render(){
return(
<View>
<View style={{height:220,backgroundColor:'#DCDCDC'}}>
<Image style={{width:120,height:120,top:50,left:120,backgroundColor:'red'}}
source={require('./download.png')} />
</View>
<View style={{top:30}}>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<TouchableOpacity style= { styles.views}
onPress = {()=>{ Actions.First({customData: 'Hello!'}) }}>
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> Profile </Text>
</TouchableOpacity>
<TouchableOpacity style= { styles.views1} >
<Text style={{fontSize:20, textAlign:'center',color:'white',top:20}}> Health Tracker </Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
In the above code, Actions in not working means not navigating to First.js page, how can i edit my code, and i have not written anything in ComponentWillMount() function, what i should write inside that?ataomega
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity
} from 'react-native';
import Home from './Home';
export default class Prof extends Component{
constructor(){
super()
}
render(){
return (
<Navigator
initialRoute = {{ name: 'Home', title: 'Home' }}
renderScene = { this.renderScene }
navigationBar = {
<Navigator.NavigationBar
style = { styles.navigationBar }
routeMapper = { NavigationBarRouteMapper } />
}
/>
);
}
renderScene(route, navigator) {
if(route.name == 'Home') {
return (
<Home
navigator = {navigator}
{...route.passProps}
/>
)
}
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, navState) {
if(index > 0) {
return (
<View>
<TouchableOpacity
onPress = {() => { if (index > 0) { navigator.pop() } }}>
<Text style={ styles.leftButton }>
Back
</Text>
</TouchableOpacity>
</View>
)
}
else { return null }
},
RightButton(route, navigator, index, navState) {
if (route.openMenu) return (
<TouchableOpacity
onPress = { () => route.openMenu() }>
<Text style = { styles.rightButton }>
{ route.rightText || 'Menu' }
</Text>
</TouchableOpacity>
)
},
Title(route, navigator, index, navState) {
return (
<Text style = { styles.title }>
{route.title}
</Text>
)
}
};
First of all I recommend you to create a rounter component and make your app launch from there:
Something like this
import { Scene, Router, ActionConst } from 'react-native-router-flux';
import First from 'yourRoute';
const RouterComponent = () => {
<Router>
<Scene
key="First"
component={First}
initial />
... your other scenes
</Router>
}
export default RouterComponent;
then in your index page or wherever you load from just add this component
import React, { Component } from 'react'
import RouterComponent from './Router'
class AppContainer extends Component {
render() {
return (
<RouterComponent />
);
}
}
export default AppContainer;
now you can call it from your code. Any doubts ask them :P