react navigation navigate to other screen - react-native

i try make login, when isLoggedIn = true then navigate to Profile, but always give me error
undefined is not an object (evaluating '_this.props.navigation')
whats wrong with mycode? can someone help me?
import React from 'react'
import {
Image,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View
} from 'react-native'
import { Field, reduxForm } from 'redux-form'
import { Container, Content, InputGroup, Button , Input, Icon, Item } from 'native-base';
import { login } from '../Action/Action';
import {NavigationActions} from "react-navigation";
import styles from './Style';
import { connect, } from 'react-redux'
}
function submit(values) {
console.log(values);
}
const renderInput = ({ input: { onChange, ...restInput }}) => {
return <Input onChangeText={onChange} {...restInput} />
}
}
const Form = props => {
//const {navigate} = this.props.navigation;
//let _navigateTo;
if (props.appUser.isLoggedIn) {
console.log("haloooo");
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
params: {},
action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigateAction)
}
const { handleSubmit } = props
//console.log(props.appUser);
return (
<Container >
<Content>
<Content>
<View style={styles.container}>
<Image source={require('../Assets/Octocat.png')} style={{width: 128, height: 128}} />
</View>
</Content>
<Content style={{paddingLeft:10,paddingRight:10,paddingBottom:5, paddingTop:30}}>
<Item rounded>
<Field name="username" component={renderInput} />
</Item>
</Content>
<Content style={{paddingLeft:10,paddingRight:10}}>
<Item rounded>
<Field name="password" component={renderInput} />
</Item>
</Content>
<Content style={{padding:10}}>
<Button onPress={handleSubmit(props.onLogin)} block info>
<Text>Login</Text>
</Button>
</Content>
</Content>
</Container>
)
}
const myReduxForm = reduxForm({
form: 'MyReduxForm',
})(Form)
function mapStateToProps(state) {
return {
appUser: state.appUser,
}
}
function mapDispatchToProps(dispatch) {
return {
onLogin: (data) => { dispatch(login(data)); },
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(myReduxForm)
// export default reduxForm({
// form: 'test'
// })(Form)
// export default reduxForm({
// form: 'test'
// })(Form)

try to use withNavigation. Use the component FormWithNavigation as shown in the code below
const Form = ({ navigation }) => {
//..
navigation.navigate('XXX')
}
const FormWithNavigation = withNavigation(Form);

you use this.props instead just props
this one should work
const { handleSubmit, navigation: {navigate} } = props

Related

Error when simulate change text react native with jest

Let's say I create a login screen. Inside that screen, I import form component. And inside form component I have a text input.
Then, I want to simulate text input on change text, but always get an error
Method “simulate” is meant to be run on 1 node. 0 found instead.
This is my test file
it('calls the login submit method', () => {
const fieldPhoneNumber = wrapper
.find('Form')
.dive()
.find('TextInput[id="fieldPhoneNumber"]');
fieldPhoneNumber
.at(0)
.simulate('changeText', { target: { value: '082262366193' } });
});
This is my component login file
import React, { useState, useEffect } from 'react';
import { ScrollView, StatusBar, Platform } from 'react-native';
import Header from './components/Header';
import Form from './components/Form';
import ButtonSocialMedia from './components/ButtonSocialMedia';
function LoginScreen() {
const [phoneNumber, setPhoneNumber] = useState('');
const [focus, setFocus] = useState(false);
useEffect(() => {
}, [phoneNumber]);
const changePhoneNumber = (value) => {
setPhoneNumber(value);
};
const showAppleButton = () => {
if (Platform.OS === 'ios') {
const version = Platform.Version.split('.')[0];
if (version >= 13) {
return true;
} else {
return false;
}
} else {
return false;
}
};
const loginSubmit = () => {
console.log('Login Submit');
};
return (
<ScrollView>
<StatusBar
translucent
backgroundColor="transparent"
barStyle="light-content"
/>
<Header />
<Form
phoneNumber={phoneNumber}
changePhoneNumber={(value) => changePhoneNumber(value)}
focus={focus}
setFocus={() => setFocus(true)}
loginSubmit={() => loginSubmit()} />
<ButtonSocialMedia showAppleButton={() => showAppleButton()} />
</ScrollView>
);
}
export default LoginScreen;
This is my form component
/* eslint-disable prettier/prettier */
import React from 'react';
import { View, Text, TextInput } from 'react-native';
import styles from '../styles/StyleForm';
import color from '../../../../__global__/styles/themes/colorThemes';
import regex from '../../../../constant/regex';
import * as yup from 'yup';
import { Formik } from 'formik';
import ButtonFull from '../../../../__global__/button/buttonFull';
const regexPhoneNumber = regex.phone;
function Form(props) {
const renderFocus = () => {
if (props.focus) {
return (
<Text style={styles.textFocus}>Type your phone number</Text>
);
}
};
return (
<Formik
enableReinitialize={true}
initialValues={{
phoneNumber: props.phoneNumber,
}}
onSubmit={values => {
console.log('Login Submit');
}}
validateOnMount={true}
validationSchema={yup.object().shape({
phoneNumber: yup
.string()
.required()
.min(8)
.matches(regexPhoneNumber, 'Phone number is not valid'),
})}>
{({
// values,
handleChange,
errors,
setFieldTouched,
touched,
isValid,
handleSubmit,
}) => (
<View style={styles.form}>
<View style={styles.subContainer}>
<View style={styles.containerTitle}>
<Text style={styles.textTitle}>+62</Text>
</View>
<View style={styles.containerPhoneNumber}>
{renderFocus()}
<TextInput
id={'fieldPhoneNumber'}
onFocus={() => props.setFocus(true)}
value={props.phoneNumber}
style={styles.subContainerPhoneNumber}
placeholderStyle={styles.placeholder}
placeholder={'Type your phone number'}
onChangeText={(value) => {
handleChange('phoneNumber');
props.changePhoneNumber(value);
setFieldTouched('phoneNumber', true);
}}
keyboardType={'numeric'}
onBlur={() => setFieldTouched('phoneNumber', true)}
/>
</View>
</View>
{touched.phoneNumber && errors.phoneNumber && (
<View style={styles.containerError}>
<Text style={styles.textError}>Phone number is not valid</Text>
</View>
)}
<View style={styles.containerButton}>
<ButtonFull
isDisabled={!isValid}
id={'buttonLogin'}
color={isValid ? color.thema : color.grey}
handleSubmit={() => props.loginSubmit()}
title={'Next'}
/>
</View>
</View>
)}
</Formik>
);
}
export default Form;
The error you're facing implies that the statement const fieldPhoneNumber wrapper.find('Form').dive().find('TextInput[id="fieldPhoneNumber"]'); couldn't find the TextInput component and hence the simulate function cannot be called. Try searching for the string "TextInput" inside the wrapper, and see if that works.

Unable to run react-navigation functions on customised back button in React native

The function I am not able to run is the navigation functions in my example it's
this.this.props.navigation.goBack()
My Login File is posted below but the part with the problem is the short snippet
The error I am getting is: TypeError: undefined is not an object (evaluating 'LogIn.props.navigation')
First failed Snippet
static navigationOptions = {
headerLeft: () => (
<Button
onPress={()=>this.props.navigation.goBack()}
title="cancel"
color={colors.black}
/>
),
};
LogIn.js
import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import colors from '../styles/colors';
import {
View,
Text,
ScrollView,
StyleSheet,
KeyboardAvoidingView,
Button
} from 'react-native';
import InputField from '../components/form/InputField';
import NexArrowButton from '../components/buttons/NextArrowButton';
import Notification from '../components/Notification';
export default class LogIn extends Component{
constructor(props){
super(props);
this.state ={
formValid:false,
validEmail:false,
emailAddress:'',
validPassword:false,
}
this.handleNextButton = this.handleNextButton.bind(this)
this.handleCloseNotification = this.handleCloseNotification.bind(this)
this.handleEmailChange = this.handleEmailChange.bind(this);
}
static navigationOptions = {
headerLeft: () => (
<Button
onPress={()=>this.props.navigation.goBack()}
title="cancel"
color={colors.black}
/>
),
};
handleNextButton(){
if(this.state.emailAddress === 'admin#mail.com'){
this.setState({formValid:true})
} else{
this.setState({formValid: false});
}
}
handleCloseNotification(){
this.setState({formValid:true });
}
handleEmailChange(email){
const emailCheckRegex = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const { validEmail } = this.state;
this.setState({ emailAddress: email });
if (!validEmail) {
if (emailCheckRegex.test(email)) {
this.setState({ validEmail: true });
}
} else if (!emailCheckRegex.test(email)) {
this.setState({ validEmail: false });
}
}
handlePasswordChange(password){
const { validPassword } = this.state;
this.setState({ password });
if (!validPassword) {
if (password.length > 4) {
// Password has to be at least 4 characters long
this.setState({ validPassword: true });
}
} else if (password <= 4) {
this.setState({ validPassword: false });
}
}
render(){
const {formValid, validPassword} = this.state;
const showNotification = formValid ? false:true;
const background = formValid ? colors.green01 : colors.darkOrange;
const notificationMarginTop = showNotification ? 10:0;
return(
<KeyboardAvoidingView style={[{backgroundColor:background}, styles.wrapper] } behavior="padding">
<View style={styles.ScrollViewWrapper}>
<ScrollView style={styles.ScrollView}>
<Text style={styles.loginHeader}>Log In</Text>
<InputField
labelText= "Email Address"
labelTextSize={20}
labelColor={colors.white}
textColor={colors.white}
borderBottomColor={colors.white}
inputType="email"
customStyle={{marginBottom:30}}
onChangeText={this.handleEmailChange}
/>
<InputField
labelText= "Password"
labelTextSize={20}
labelColor={colors.white}
textColor={colors.white}
borderBottomColor={colors.white}
inputType="password"
customStyle={{marginBottom:30}}
/>
</ScrollView>
<View style={styles.nextButton}>
<NexArrowButton
// handleNextButton={this.handleNextButton}
handleNextButton={()=>this.props.navigation.goBack()}
/>
</View>
<View style={[styles.notificationWrapper, {marginTop:notificationMarginTop}]}>
<Notification
showNotification={showNotification}
handleCloseNotification={this.handleCloseNotification}
type="Error"
firstLine="Those credentials don't look right."
secondLine="Please try again."
/>
</View>
</View>
</KeyboardAvoidingView>
)
}
}
const styles = StyleSheet.create({
wrapper:{
display:'flex',
flex:1,
},
ScrollViewWrapper:{
marginTop:60,
flex:1,
},
ScrollView:{
paddingLeft:30,
paddingRight:30,
paddingTop:10,
flex:1,
},
loginHeader:{
fontSize:34,
color:colors.white,
fontWeight:'300',
marginBottom:40,
},
nextButton:{
position:'absolute',
right:20,
bottom:20,
},
notificationWrapper:{
position: 'absolute',
bottom:0,
zIndex:9
}
});
The most confusing part is that the second snippet below of Login.js works perfectly and it is essentially the same thing which means that I am getting the props right, but still get the error in customised back button.
Second working snippet
<View style={styles.nextButton}>
<NexArrowButton
// handleNextButton={this.handleNextButton}
handleNextButton={()=>this.props.navigation.goBack()}
/>
</View>
App.js
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import LoggedOut from './src/screens/LoggedOut';
import LogIn from './src/screens/LogIn';
import LoggedIn from './src/screens/LoggedIn';
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
const RootStack = createStackNavigator(
{
LoggedOut: LoggedOut,
LogIn: LogIn,
},
{
initialRouteName: 'LoggedOut',
}
);
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
The error in more details
I really appreciate your help ! I am happy to provide more code if it makes it easier to debugg.
You have to change the static navigationOptions to following snippet if you want to access navigation properties in a static function:
static navigationOptions = ({ navigation }) => ({
headerLeft: () => (
<Button
onPress={()=>navigation.goBack()}
title="cancel"
color={colors.black}
/>
),
});
You don't need the this.props in this case ;) The static function does not have access to the this context so this.props will not work.

Passing of variables assigned from one screen to another

basically I need to pass over a parameter called tempRole over from Login to MainTabNavigator and create tabs accordingly to user role. For example, vendor have 4 tabs and others just 3 tabs. However, I can't seem to get the role passed over though.
From Login
import React from 'react';
import { Text, View, StyleSheet, Platform, TextInput, TouchableOpacity } from 'react-native';
import firebase from 'firebase';
import { Container, Form, Item, Label, Input, Button } from "native-base";
import * as FirebaseAPI from '../modules/firebaseAPI';
import MainTabNavigator from '../navigation/MainTabNavigator';
import bottomTabNavigator from '../navigation/MainTabNavigator';
export default class LoginScreen extends React.Component {
constructor(props) {
super(props);
}
static navigationOptions = {
title: 'Login',
};
state = {
LoginEmail: "",
LoginPassword: "",
};
componentDidMount() {
this.watchAuthState(this.props.navigation)
try {
window = undefined;
} catch (e) {
}
}
watchAuthState(navigation) {
firebase.auth().onAuthStateChanged(function(user) {
console.log('onAuthStateChangedLOGIN: ', user)
if (user) {
// user.displayName will be like vendor.Peter
// e.g. role.name
var tempName = user.displayName;
navigation.navigate('Main', {
userRole: tempName.substr(0,tempName.indexOf('.'))
});
}
});
}
signIn(LoginEmail, LoginPassword) {
FirebaseAPI.signInUser(LoginEmail, LoginPassword);
}
render() {
return (
<Container style={styles.container}>
<Form>
<Text style={styles.text}>Login</Text>
<Item style={styles.standardDefaultInput} floatingLabel>
<Label style={{textAlign: 'center'}}>Email (example#example.com)</Label>
<Input
autoCapitalize="none"
style={{textAlign: 'center'}}
autoCorrect={false}
onChangeText={(text) => this.setState({LoginEmail: text})}
value={this.state.LoginEmail}
/>
</Item>
<Item style={styles.standardDefaultInput} floatingLabel>
<Label style={{textAlign: 'center'}}>Password (min. 6 charatcers)</Label>
<Input
autoCapitalize="none"
style={{textAlign: 'center'}}
autoCorrect={false}
onChangeText={(text) => this.setState({LoginPassword: text})}
value={this.state.Password}
/>
</Item>
<Button style={styles.standardDefaultButton} onPress={() => this.setState(this.signIn(this.state.LoginEmail, this.state.LoginPassword))} full rounded success>
<Text>Log In</Text>
</Button>
<Button style={styles.standardDefaultButton} onPress={() => this.props.navigation.navigate('SignUp')} full rounded link>
<Text>Sign Up</Text>
</Button>
</Form>
</Container>
);
};
}
Do take note that the navigation to Main is to the TabNavigator
From MainTabNavigator
let bottomTabNavigator = null
//let user = navigation.getParam(user)
//let userRole = user.displayName.substr(0,user.displayName.indexOf('.'))
//const { navigation } = this.props;
// The above failed
let userRole = navigation.getParam('userRole');
if (userRole == "vendor") {
bottomTabNavigator = createBottomTabNavigator({
HomeStack,
ListingStack,
CalendarStack,
ProfileStack
});
} else {
bottomTabNavigator = createBottomTabNavigator({
HomeStack,
CalendarStack,
ProfileStack
});
}
export default bottomTabNavigator
Use the global function to pass the value.
Global functions are useful when you need to pass data to a screen that is not a relationship between parents and children.
Global function Screen:
let NICKNAME = "";
function setNickName(data) {
NICKNAME = data;
}
function getNickName() {
return NICKNAME;
}
export {setNickName,getNickName }
senddata Screen:
import {setNickName} from "GlobalFunctionScreen"
...
this.state={
data: "sendData"
}
...
componentDidMount(){
setNickName(this.state.data);
}
receive data Screen:
import {getNickName} from "GlobalFunctionScreen"
...
componentDidMount(){
data = getNickName();
alert(data);
}

type error undefined name property in react native components

I am getting type error of undefined name property I believe in my EmployeeEdit.js file. When I touch one item on the employee list I get this error instead of going to employee edit form with the passed parameter. I console logged and found state.employeeForm is not loading the values { name, phone, shift } from EmployeeFormReducer. I m not sure why.
here's the error
TypeError: Cannot read property 'name' of undefined
This error is located at:
in Connect(EmployeeForm) (at EmployeeEdit.js:21)
in RCTView (at View.js:113)
in View (at Card.js:6)
in Card (at EmployeeEdit.js:20)
in EmployeeEdit (created by Connect(EmployeeEdit))
in Connect(EmployeeEdit) (at SceneView.js:35)
in SceneView (at CardStack.js:413)
in RCTView (at View.js:113)
in View (at createAnimatedComponent.js:134)
in AnimatedComponent (at Card.js:28)
in Card (at PointerEventsContainer.js:55)
in Container (at CardStack.js:443)
in RCTView (at View.js:113)
in View (at CardStack.js:373)
in RCTView (at View.js:113)
in View (at CardStack.js:372)
in CardStack (at CardStackTransitioner.js:110)
in RCTView (at View.js:113)
in View (at Transitioner.js:192)
in Transitioner (at CardStackTransitioner.js:60)
in CardStackTransitioner (at StackNavigator.js:48)
in Unknown (at createNavigator.js:36)
in Navigator (at createNavigationContainer.js:198)
in NavigationContainer (at App.js:37)
in Provider (at App.js:36)
in App (at renderApplication.js:35)
in RCTView (at View.js:113)
in View (at AppContainer.js:102)
in RCTView (at View.js:113)
in View (at AppContainer.js:126)
in AppContainer (at renderApplication.js:34)
EmployeeEdit.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import _ from 'lodash';
import EmployeeForm from './EmployeeForm';
import { employeeUpdate } from '../actions';
import { Card, CardSection, Button } from './common';
class EmployeeEdit extends Component {
componentWillMount() {
_.each(this.props.navigation.state.params.employee, (value, prop) => {
this.props.employeeUpdate({ prop, value });
});
}
onButtonPress() {
const { params } = this.props.navigation.state;
const { name, phone, shift } = params.employee;
}
render() {
return (
<Card>
<EmployeeForm {...this.props} />
<CardSection>
<Button onPress={() => this.onButtonPress.bind(this)}>
Save Changes
</Button>
</CardSection>
</Card>
);
}
}
const mapStateToProps = (state) => {
const { name, phone, shift } = state.employeeForm;
return { name, phone, shift };
};
export default connect(mapStateToProps, { employeeUpdate })(EmployeeEdit);
EmployeeList.js
import React, { Component } from 'react';
import { FlatList } from 'react-native';
import { connect } from 'react-redux';
//import { R } from 'ramda';
import _ from 'lodash';
import { employeesFetch } from '../actions';
import { HeaderButton } from './common';
import ListEmployee from './ListEmployee';
class EmployeeList extends Component {
static navigationOptions = ({ navigation }) => ({
headerRight: (
<HeaderButton onPress={() => navigation.navigate('employeeCreate')}>
Add
</HeaderButton>
)
});
componentWillMount() {
this.props.employeesFetch();
}
keyExtractor(item) {
return item.uid;
}
renderItem({ item }) {
return <ListEmployee employee={item} navigation={this.props.navigation} />;
}
render() {
return (
<FlatList
data={this.props.employees}
renderItem={this.renderItem.bind(this)} // Only for test
keyExtractor={this.keyExtractor}
navigation={this.props.navigation}
/>
);
}
}
const mapStateToProps = (state) => {
const employees = _.map(state.employees, (val, uid) => ({ ...val, uid }));
return { employees };
};
export default connect(mapStateToProps, { employeesFetch })(EmployeeList);
ListEmployee.js
import React, { Component } from 'react';
import {
Text,
StyleSheet,
TouchableWithoutFeedback,
View
} from 'react-native';
import { CardSection } from './common';
class ListEmployee extends Component {
render() {
const { employee } = this.props;
const { navigate } = this.props.navigation;
const { textStyle } = styles;
const { name } = this.props.employee;
return (
<TouchableWithoutFeedback onPress={() => navigate('employeeEdit', { employee })}>
<View>
<CardSection>
<Text style={textStyle}>{name}</Text>
</CardSection>
</View>
</TouchableWithoutFeedback>
);
}
}
/**
second argument in connect does 2 things. 1. dispatches all actions creators
return action objects to the store to be used by reducers; 2. creates props
of action creators to be used by components
**/
export default ListEmployee;
const styles = StyleSheet.create({
textStyle: {
fontSize: 18,
paddingLeft: 15,
}
});
EmployeeForm.js
import React, { Component } from 'react';
import { Picker, Text, StyleSheet, View } from 'react-native';
import { connect } from 'react-redux';
import { employeeUpdate } from '../actions';
import { CardSection, Input } from './common';
class EmployeeForm extends Component {
render() {
return (
<View>
<CardSection>
<Input
label="Name"
placeholder="Jane"
value={this.props.name}
onChangeText={value => this.props.employeeUpdate({ prop: 'name', value })}
/>
</CardSection>
<CardSection>
<Input
label="Phone"
placeholder="xxx-xxxx"
value={this.props.phone}
onChangeText={value => this.props.employeeUpdate({ prop: 'phone', value })}
/>
</CardSection>
<CardSection>
<Text style={styles.pickerTextStyle}>Shift</Text>
<Picker
style={{ flex: 1 }}
selectedValue={this.props.shift}
onValueChange={value => this.props.employeeUpdate({ prop: 'shift', value })}
>
<Picker.Item label="Monday" value="Monday" />
<Picker.Item label="Tuesday" value="Tuesday" />
<Picker.Item label="Wednesday" value="Wednesday" />
<Picker.Item label="Thursday" value="Thursday" />
<Picker.Item label="Friday" value="Friday" />
<Picker.Item label="Saturday" value="Saturday" />
<Picker.Item label="Sunday" value="Sunday" />
</Picker>
</CardSection>
</View>
);
}
}
const styles = StyleSheet.create({
pickerTextStyle: {
fontSize: 18,
paddingLeft: 20
}
});
const mapStateToProps = (state) => {
const { name, phone, shift } = state.EmployeeForm;
return { name, phone, shift };
};
export default connect(mapStateToProps, { employeeUpdate })(EmployeeForm);
here's my combineReducers
import { combineReducers } from 'redux';
import AuthReducer from './AuthReducer';
import EmployeeFormReducer from './EmployeeFormReducer';
import EmployeeReducer from './EmployeeReducer';
import SelectionReducer from './SelectionReducer';
export default combineReducers({
auth: AuthReducer,
employeeForm: EmployeeFormReducer,
employees: EmployeeReducer,
selectedEmployeeId: SelectionReducer
});
here's EmployeeFormReducer
import { EMPLOYEE_UPDATE, EMPLOYEE_CREATE } from '../actions/types';
const INITIAL_STATE = {
// prop: 'name', value: ''
name: '',
phone: '',
shift: ''
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case EMPLOYEE_UPDATE:
// [] is NOT an array; a syntax to convert value into key; called key interpolation??
return { ...state, [action.payload.prop]: action.payload.value };
case EMPLOYEE_CREATE:
return INITIAL_STATE;
default:
return state;
}
};
here's the action creator
export const employeeUpdate = ({ prop, value }) => {
return {
type: EMPLOYEE_UPDATE,
payload: { prop, value }
};
};
Here's the EmployeeForm.js
import React, { Component } from 'react';
import { Picker, Text, StyleSheet, View } from 'react-native';
import { connect } from 'react-redux';
import { employeeUpdate } from '../actions';
import { CardSection, Input } from './common';
class EmployeeForm extends Component {
render() {
return (
<View>
<CardSection>
<Input
label="Name"
placeholder="Jane"
value={this.props.name}
onChangeText={value => this.props.employeeUpdate({ prop: 'name', value })}
/>
</CardSection>
<CardSection>
<Input
label="Phone"
placeholder="xxx-xxxx"
value={this.props.phone}
onChangeText={value => this.props.employeeUpdate({ prop: 'phone', value })}
/>
</CardSection>
<CardSection>
<Text style={styles.pickerTextStyle}>Shift</Text>
<Picker
style={{ flex: 1 }}
selectedValue={this.props.shift}
onValueChange={value => this.props.employeeUpdate({ prop: 'shift', value })}
>
<Picker.Item label="Monday" value="Monday" />
<Picker.Item label="Tuesday" value="Tuesday" />
<Picker.Item label="Wednesday" value="Wednesday" />
<Picker.Item label="Thursday" value="Thursday" />
<Picker.Item label="Friday" value="Friday" />
<Picker.Item label="Saturday" value="Saturday" />
<Picker.Item label="Sunday" value="Sunday" />
</Picker>
</CardSection>
</View>
);
}
}
const styles = StyleSheet.create({
pickerTextStyle: {
fontSize: 18,
paddingLeft: 20
}
});
const mapStateToProps = (state) => {
const { name, phone, shift } = state.EmployeeForm;
return { name, phone, shift };
};
export default connect(mapStateToProps, { employeeUpdate })(EmployeeForm);
I think that your problem is that you are not binding. Try this:
onButtonPress = () => {
const { params } = this.props.navigation.state;
const { name, phone, shift } = params.employee;
}
The issue was EmployeeForm.js; this is a common component shared between EmployeeEdit.js and EmployeeForm.js. It receives from either of the 2 but it must not have a mapStateToProps as it ends up overriding its parent's mapStateToProps who is responsible to manage the redux state. So I got rid of it and combinereducers was properly able to match state.key to its corresponding value ie reducers declared in its functional call.

react-native gives error on displaying image

recently started working on an app using https://github.com/start-react/native-starter-kit
Heres my component:
import React, { Component } from "react";
import { TouchableOpacity } from "react-native";
import { connect } from "react-redux";
import BlankPage2 from "../blankPage2";
import DrawBar from "../drawBar";
import TopNav from "../topNav";
import { DrawerNavigator, NavigationActions } from "react-navigation";
import {
Container,
Header,
Title,
Content,
Text,
Button,
Icon,
Left,
Body,
Right,
Image,
} from "native-base";
import { Grid, Row } from "react-native-easy-grid";
import { setIndex } from "../../actions/list";
import { openDrawer } from "../../actions/drawer";
import styles from "./styles";
class News extends Component {
static navigationOptions = {
header: null
};
render() {
return (
<Container style={styles.container}>
<Header>
<Left>
<Button
transparent
onPress={() => DrawerNav.navigate("DrawerOpen")}>
<Icon active name="menu" />
</Button>
</Left>
<Body>
<Title>News</Title>
</Body>
<Right>
</Right>
</Header>
<Content scrollEnabled={false}>
<TopNav navigation={this.props.navigation}></TopNav>
<Grid style={styles.mt}>
{this.props.list.map((item, i) => (
<Row key={i}>
<TouchableOpacity
style={styles.row}
onPress={() =>
this.props.navigation.navigate("BlankPage", {
name: { item }
})}>
<Image source={{uri: 'https://i.vimeocdn.com/portrait/58832_300x300.jpg'}} />
<Text style={styles.text}>{item}</Text>
</TouchableOpacity>
</Row>
))}
</Grid>
</Content>
</Container>
);
}
}
function bindAction(dispatch) {
return {
setIndex: index => dispatch(setIndex(index)),
openDrawer: () => dispatch(openDrawer())
};
}
const mapStateToProps = state => ({
name: state.user.name,
list: state.list.list
});
const NewsSwagger = connect(mapStateToProps, bindAction)(News);
const DrawNav = DrawerNavigator(
{
News: { screen: NewsSwagger },
BlankPage2: { screen: BlankPage2 }
},
{
contentComponent: props => <DrawBar {...props} />
}
);
const DrawerNav = null;
DrawNav.navigationOptions = ({ navigation }) => {
DrawerNav = navigation;
return {
header: null
};
};
export default DrawNav;
And of course, heres my error:
And i have no clue why this is happening. As soon as i remove the Image tag, error goes away. I can't really export the News Component, becouse i am using the Drawer thingy(check starter-kit-demo).
Edit: Error happens on IOS. Iphone 6 emulator.
You are importing Image from native-base when you should be importing it from react-native
import {
Container,
Header,
Title,
Content,
Text,
Button,
Icon,
Left,
Body,
Right,
Image // remove this one
} from "native-base";
And add
import {
TouchableOpacity,
Image
} from "react-native";
Also you'll have to add a height & width for a proper render.
<Image
style={{width: 300, height: 300}}
source={{uri: 'https://i.vimeocdn.com/portrait/58832_300x300.jpg'}}
/>