cant find variable props - reactjs

I am trying to show the detail view when user taps on one of the list item. When the user taps on the listitem, I get an error saying Undefined is not an object
evaluating 'this.props.services.ser. Below is the screen shot of the error:
My list item page code is below:
import React, { Component } from 'react';
import { Text, View, StyleSheet, ListView } from 'react-native';
import { Provider, connect } from 'react-redux';
import { createStore } from 'redux'
import reducers from '../reducers/ServiceReducer';
import ServiceItem from './ServiceItem';
import Icon from 'react-native-vector-icons/EvilIcons';
import ServiceDetail from './ServiceDetail';
const styles = StyleSheet.create({
container: {
flex: 1,
width: 353,
flexWrap: 'wrap',
paddingTop: 20,
paddingLeft: 20,
},
});
const store = createStore(reducers);
class AutoCompActivity extends Component {
renderInitialView() {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.dataSource = ds.cloneWithRows(this.props.services);
if (this.props.detailView === true) {
return (
<ServiceDetail />
);
} else {
return (
<ListView
enableEmptySections={true}
dataSource={this.dataSource}
renderRow={(rowData) =>
<ServiceItem services={rowData} />
}
/>
);
}
}
render() {
return (
<View style={styles.container}>
{this.renderInitialView()}
</View>
);
}
}
const mapStateToProps = state => {
return {
services: state.services,
detailView: state.detailView,
};
};
const ConnectedAutoCompActivity = connect(mapStateToProps)(AutoCompActivity);
const app1 = () => (
<Provider store={store}>
<ConnectedAutoCompActivity />
</Provider>
)
export default app1;
Each item that I display to the user is defined in js class serviceItem.js. Below is the code for serviceItem.js. I put the entire code inside TouchableWithoutFeedback. This is when I am getting an error when user taps on one of the listItem. I looked at this code several times, but could not figure out where I am doing wrong
import React from 'react';
import { Text, View, StyleSheet, Image, TouchableWithoutFeedback } from 'react-native';
import { connect } from 'react-redux';
import { getTheme } from 'react-native-material-kit';
import Icon from 'react-native-vector-icons/EvilIcons';
import * as actions from '../actions';
const theme = getTheme();
const styles = StyleSheet.create({
card: {
marginTop: 20,
},
title: {
top: 20,
left: 80,
fontSize: 24,
},
image: {
height: 100,
},
action: {
backgroundColor: 'black',
color: 'white',
},
icon: {
position: 'absolute',
top: 15,
left: 0,
color: 'white',
backgroundColor: 'rgba(255,255,255,0)',
},
});
const ServiceItem = (props) => {
return (
<TouchableWithoutFeedback
onPress={() => props.selectServices(props.services)}
>
<View style={[theme.cardStyle, styles.card]}>
<Text >{props.services.ser} </Text>
</View>
</TouchableWithoutFeedback>
);
};
const mapStateToProps = state => {
return {
selectServices: state.selectServices,
services: state.services
};
};
export default connect(mapStateToProps, actions)(ServiceItem);
When the user taps on each listitem. I am calling the class ServiceDetail.js. Below is the code for serviceDetail.js class:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import { Text, View, StyleSheet, Image, ScrollView, TouchableOpacity, Linking } from 'react-native';
import { connect } from 'react-redux';
import { getTheme } from 'react-native-material-kit';
import EvilIcon from 'react-native-vector-icons/EvilIcons';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import SimpleIcon from 'react-native-vector-icons/SimpleLineIcons';
import * as actions from '../actions';
const theme = getTheme();
const styles = StyleSheet.create({
card: {
marginTop: 10,
paddingBottom: 20,
marginBottom: 20,
borderColor: 'lightgrey',
borderWidth: 0.5,
},
title1: {
top: 10,
left: 80,
fontSize: 24,
},
title2: {
top: 35,
left: 82,
fontSize: 18,
},
image: {
flex: 0,
height: 100,
width: 333,
backgroundColor: 'transparent',
justifyContent: 'center',
alignItems: 'center',
},
closeIcon: {
position: 'absolute',
top: 5,
left: 295,
color: 'rgba(233,166,154,0.8)',
backgroundColor: 'rgba(255,255,255,0)',
},
icon: {
position: 'absolute',
top: 15,
left: 0,
color: 'white',
backgroundColor: 'rgba(255,255,255,0)',
},
textArea: {
flexDirection: 'row',
paddingLeft: 20,
paddingTop: 10,
width: 260,
},
textIcons: {
color: '#26a69a',
},
actionArea: {
paddingTop: 10,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
});
class ServiceDetail extends Component {
handleClick = (link) => {
Linking.canOpenURL(link).then(suppported => {
if (supported) {
Linking.openURL(link);
} else {
console.log('Don\'t know how to open URI: ' + link);
}
});
};
render() {
return (
<ScrollView showsVerticalScrollIndicator={false}>
<View style={[theme.cardStyle, styles.card]}>
<Image
source={require('../images/background.jpg')}
style={[theme.cardImageStyle, styles.image]}
/>
<EvilIcon name={'user'} size={100} style={styles.icon}/>
<SimpleIcon name={'close'} size={30} style={styles.closeIcon}
onPress={() => this.props.noneSelected()} />
<Text style={[theme.cardTitleStyle, styles.title1]}>{this.props.services.ser}</Text>
<Text style={[theme.cardTitleStyle, styles.title2]}>from {this.props.services.Location}</Text>
<Text style={[theme.cardTitleStyle, styles.title2]}>from {this.props.services.SecondLoc}</Text>
<View style={styles.textArea}>
<MaterialIcon name={'phone'} size={40} style={styles.textIcons}/>
<Text style={theme.cardContentStyle}>{this.props.services.Phone}</Text>
</View>
<View style={styles.textArea}>
<MaterialIcon name={'email'} size={40} style={styles.textIcons}/>
<Text style={theme.cardContentStyle}>{this.props.services.email}</Text>
</View>
<View style={styles.actionArea}>
<Text>Call</Text>
<Text>Email</Text>
</View>
</View>
</ScrollView>
);
}
}
const mapStateToProps = state => {
return {
service: state.serviceSelected,
};
};
export default connect(mapStateToProps, actions)(ServiceDetail);
My index.js class has the following code under actions folder:
export const selectServices = (serviceId) => {
return {
type: 'SELECTED_SERVICE',
payload: serviceId,
};
};
export const noneSelected = () => {
return {
type: 'NONE_SELECTED',
};
};
My serviceReducer has the following code:
import services from './services.json';
const initialState = {
services,
detailView: false,
serviceSelected: null,
};
export default (state = initialState, action) => {
switch (action.type) {
case 'SELECTED_SERVICE':
return {
...state,
detailView: true,
serviceSelected: action.payload
}
case 'NONE_SELECTED':
return {
...state,
detailView: false,
serviceSelected: null,
}
default:
return state;
}
}
I am developing this application on windows machine on android emulator. I know I am missing something. I looked at each and every line, but could not figure out what am I doing wrong. I am new to react native and trying to follow the example to make this app. I tried to debug the application using chrome, but keep getting an error that could not connect to remote debugging.
any help will be highly appreciated.

I see you pass props and use it to your const ServiceItem. You need to use mapStateToProps also then pass to your connect at serviceItem.js.
const mapStateToProps = state => {
return {
selectServices: state.selectServices,
services: state.services
};
};
export default connect(mapStateToProps, actions)(ServiceItem);
Your ServiceDetail.js also should be:
const mapStateToProps = state => {
return {
services: state.services
};
};
export default connect(mapStateToProps, actions)(ServiceDetail);

Your ServiceItem component is just a presentational component, in my opinion, it need not to be connected to redux store, instead, pass the data and event hook from parent to ServiceItem component and that will work just fine. That will solve your props problem as well.
Point made by "DennisFrea" still holds good. i am just suggesting another of achieving the same thing.

Related

Mobx not updating react native element

I'm new to react and mobx.
I'm trying to use mobx to update a simple counter and display the count number.
When I click on the button "Add" I can see in the logs that counterStore.count is increasing but counter shown in the <Text></Text> remains equal to 0.
Can you please me tell me what is wrong?
index.tsx
import { observer } from "mobx-react";
import React from "react";
import { Button, StyleSheet, Text, View } from "react-native";
import CounterStore from './stores/CounterStore';
export function App() {
const counterStore = new CounterStore(0);
return (
<View style={styles.container}>
<View style={styles.wrapper}>
<Text>{counterStore.count}</Text>
<Button
title="Add"
onPress={() => {
counterStore.addToCount();
console.log("count = ", counterStore.count);
}}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
height: "100%"
},
wrapper: {
backgroundColor: "#F5FCFF",
width: "100%",
maxWidth: 425
}
});
export default observer(App);
CounterStore.ts
import { action, makeObservable, observable } from "mobx";
class CounterStore {
#observable count: number;
constructor(count: number){
this.count = count
makeObservable(this);
}
#action
addToCount(){
this.count++;
}
}
export default CounterStore;
Output & Logs
output
I tried to improve my code based on Jay Vaghasiya's answer, but still got the same behaviour.
CounterStore.ts
import { action, makeObservable, observable } from "mobx";
import React from "react";
class CounterStore {
count = 0;
constructor(){
makeObservable(this), {count: observable};
}
#action
addToCount(){
this.count++;
}
}
export const CounterStoreContext = React.createContext(new CounterStore());
index.tsx
import { observer } from "mobx-react";
import React from "react";
import { Button, StyleSheet, Text, View } from "react-native";
import { CounterStoreContext } from './stores/CounterStore';
const App = observer(() => {
const counterStore = React.useContext(CounterStoreContext);
return (
<View style={styles.container}>
<Text>{counterStore.count}</Text>
<Button
title="Add"
onPress={() => {
counterStore.addToCount();
console.log("count = ", counterStore.count);
}}
/>
</View>
);
});
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
height: "100%",
},
wrapper: {
backgroundColor: "#F5FCFF",
width: "100%",
maxWidth: 425
}
});
export default App;

Call setstate inside NavigationOptions React native

I'm trying to change value of state inside navigationOptions.
my navigation options
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
// alert(params.searchText);
return {
headerLeft: (params.searchText) ? <View
style={{
flexDirection:
'row', justifyContent: 'center'
}}>
<TouchableOpacity
onPress={()=> {
// navigation.navigate('home');
alert('Coming soon ');
}}>
<Image style={{ marginLeft: 20, height: 20, width: 20, resizeMode: "contain" }}
source={require('../assets/header_icons/three_logo.png')}
/>
</TouchableOpacity>
</View> :
<View style={{
flexDirection:
'row', justifyContent:
'center'
}}>
<TouchableOpacity
onPress={()=> {
this.setState({
loadUrl: "card.html#!/customer-dashboard?userType=Authenticated",
showWeb:true,
});
}}>
<Image style={{ marginLeft: 20, height: 20, width: 20, resizeMode: "contain" }}
source={require('../assets/header_icons/icon_arrow_left.png')}
/>
</TouchableOpacity>
</View>,
}
}
It's throwing this.setState is not an function
Please let me know how to achieve this. How can we change value of state from static navigationOptions
You can use redux store.
store.js
import ReduxThunk from "redux-thunk";
import { createStore, combineReducers, applyMiddleware } from "redux";
import authReducer from "./reducers/auth";
import dashboardReducer from "./reducers/dashboard";
import profileReducer from "./reducers/profile";
const rootReducer = combineReducers({
auth: authReducer,
dashboard: dashboardReducer,
profile: profileReducer
});
export default createStore(rootReducer, applyMiddleware(ReduxThunk));
Dashboard.js
import React, { Component } from "react";
import {
View,
Text,
Image,
StyleSheet,
Dimensions,
TouchableOpacity,
ScrollView,
ActivityIndicator
} from "react-native";
import OrientationScreen from "./OrientationScreen";
import { connect, useDispatch } from "react-redux";
import store from "../store/store";
class Dashboard extends Component {
render() {
const dashboard = this.props;
if (dashboard.orientation) {
return <OrientationScreen />;
} else {
return (
<View style={styles.screen}>
{this.props.dashboard.loading && (
<View style={styles.loading}>
<ActivityIndicator color={Colors.blueButton} size="large" />
</View>
)}
<Text>You are logged in</Text>
</View>
);
}
}
_openOrientation() {
store.dispatch(dashboardActions.openOrientation());
}
static navigationOptions = ({ navigation, navigationOptions }) => {
const params = navigation.state.params || {};
return {
headerTitle: "Dashboard",
headerRight: (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
Title="Orientation"
iconName="ios-help-circle-outline"
iconSize={30}
onPress={params.openOrientation}
/>
<Item
Title="Menu"
iconName="ios-menu"
iconSize={30}
onPress={() => navigation.toggleDrawer()}
/>
</HeaderButtons>
)
};
}
}
const mapStateToProps = state => {
const { auth, dashboard } = state;
return { auth, dashboard };
};
export default connect(mapStateToProps)(Dashboard);
actions/dashboard.js
const openOrientation = () => {
return dispatch => {
return dispatch({
type: "OPEN_ORIENTATION"
});
};
};
export default {
openOrientation
};
reducers/dashboard.js
const initialState = {
loading: false,
error: null,
orientation: false,
UserData: null
};
export default (state = initialState, action) => {
switch (action.type) {
case "OPEN_ORIENTATION":
return {
...state,
orientation: true
};
case "CLOSE_ORIENTATION":
return {
...state,
orientation: false
};
case "LOADING":
return {
...state,
error: null,
loading: true
};
default:
return state;
}
};
SwiperFlatList.js
import React, { PureComponent } from "react";
import { Text, Dimensions, Image, StyleSheet, View } from "react-native";
import SwiperFlatList from "react-native-swiper-flatlist";
export default class OrientationScreen extends PureComponent {
constructor(props) {
super(props);
this.state = {
images: [
require("../assets/images/SLIDE-1.jpg"),
require("../assets/images/SLIDE-2.jpg"),
require("../assets/images/SLIDE-3.jpg"),
require("../assets/images/SLIDE-4.jpg"),
require("../assets/images/SLIDE-5.jpg"),
require("../assets/images/SLIDE-6.jpg"),
require("../assets/images/SLIDE-7.jpg"),
require("../assets/images/SLIDE-8.jpg"),
require("../assets/images/SLIDE-9.jpg"),
require("../assets/images/SLIDE-10.jpg"),
require("../assets/images/SLIDE-11.jpg"),
require("../assets/images/SLIDE-12.jpg"),
require("../assets/images/SLIDE-13.jpg"),
require("../assets/images/SLIDE-14.jpg"),
require("../assets/images/SLIDE-15.jpg"),
require("../assets/images/SLIDE-16.jpg"),
require("../assets/images/SLIDE-17.jpg"),
require("../assets/images/SLIDE-18.jpg"),
require("../assets/images/SLIDE-19.jpg"),
require("../assets/images/SLIDE-20.jpg"),
require("../assets/images/SLIDE-21.jpg"),
require("../assets/images/SLIDE-22.jpg"),
require("../assets/images/SLIDE-23.jpg"),
require("../assets/images/SLIDE-24.jpg"),
require("../assets/images/SLIDE-25.jpg"),
require("../assets/images/SLIDE-26.jpg"),
require("../assets/images/SLIDE-27.jpg"),
require("../assets/images/SLIDE-28.jpg"),
require("../assets/images/SLIDE-29.jpg"),
require("../assets/images/SLIDE-30.jpg"),
require("../assets/images/SLIDE-31.jpg"),
require("../assets/images/SLIDE-32.jpg")
]
};
}
render() {
const orientationBody = this.state.images.map((item, i) => {
return (
<View key={i} style={styles.child}>
<Image
source={item}
resizeMode="contain"
style={styles.imageprofile}
/>
</View>
);
});
return (
<View style={styles.container}>
<SwiperFlatList
index={0}
removeClippedSubviews={false}
showPagination={false}
>
{orientationBody}
</SwiperFlatList>
</View>
);
}
}
export const { width, height } = Dimensions.get("window");
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white"
},
child: {
height: height * 0.8,
width,
justifyContent: "center"
},
text: {
fontSize: width * 0.5,
textAlign: "center"
},
imageprofile: {
width: "100%"
}
});

React Native Navigation with React Native Admob About

I created a 3 page application with React native navigation. Admob ads are on the 3rd page. I want to try the same ad code on all three screens. If there is any idea in this matter, please share. Thank you.
For better understanding I give the following expo code.
import React, { Component } from 'react';
import {
WebView,
AppRegistry,
StyleSheet,
Text,
View,
Button,
Alert
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import ListComponent from './ListComponent';
class App extends Component {
static navigationOptions = {
title: 'App',
};
OpenSecondActivityFunction = () => {
this.props.navigation.navigate('Second');
};
render() {
return (
<View style={styles.container}>
<Button
onPress={this.OpenSecondActivityFunction}
title="Open Second Activity"
/>
</View>
);
}
}
class SecondActivity extends Component {
static navigationOptions = {
title: 'SecondActivity',
};
OpenThirdActivityFunction = data => {
this.props.navigation.navigate('Third');
};
render() {
return (
<View style={{ flex: 1 }}>
<ListComponent
OpenThirdActivityFunction={this.OpenThirdActivityFunction}
/>
</View>
);
}
}
class ThirdActivity extends Component {
static navigationOptions = {
title: 'ThirdSecondActivity',
};
render() {
return (
<View style={{ flex: 1 }}>
<Text>3</Text>
</View>
);
}
}
const ActivityProject = StackNavigator({
First: { screen: App },
Second: { screen: SecondActivity },
Third: { screen: ThirdActivity },
});
export default ActivityProject;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
Listcomponent.js
import React, { Component } from 'react';
import {
AppRegistry,
View,
Text,
FlatList,
ActivityIndicator,
} from 'react-native';
import { List, ListItem, SearchBar } from 'react-native-elements';
class ListComponents extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
page: 1,
seed: 1,
error: null,
refreshing: false,
};
}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '98%',
backgroundColor: '#CED0CE',
marginLeft: '2%',
}}
/>
);
};
renderHeader = () => {
return <SearchBar placeholder="Type Here..." lightTheme round />;
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: '#CED0CE',
}}>
<ActivityIndicator animating size="large" />
</View>
);
};
render() {
return (
<List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }}>
<FlatList
data={[{ name: 1, coders: 2 }]}
renderItem={({ item }) => (
<ListItem
roundAvatar
title={`${item.name}`}
subtitle={item.coders}
containerStyle={{ borderBottomWidth: 0 }}
onPress={() => this.props.OpenThirdActivityFunction(item.coders)}
/>
)}
keyExtractor={item => item.coders}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={this.renderFooter}
/>
</List>
);
}
}
export default ListComponents;

Child component won't render from function

I am trying to render a child component using the function renderHowManyAlcohol()
The component LYDSelectNumber doesn't render, the correct props are being passed down, any ideas why this doesn't render?
render() {
return (
<Flexible>
<LYDSceneContainer
goBack={this.props.goBack}
subSteps={this.props.subSteps}>
<Flexible>
{this.renderHowManyAlcohol()}
</Flexible>
</LYDSceneContainer>
</Flexible>
);
}
renderHowManyAlcohol() {
return (
<View style={styles.HowManyAlcoholContainer}>
<Text>this renders</Text>
// this component below doesn't
<LYDSelectNumber
selectedNumberValue={this.props.selectedNumberValue}
onChangeNumber={this.props.onChangeNumber}
/>
</View>
);
}
LYDSelectNumber component, styles.container shows as a number '60', which is weird, I have the styles at the bottom of the page.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Picker, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import * as theme from '../../../theme';
const Item = Picker.Item;
export const SelectedNumber = ({ value = 0, displayPicker = () => {} } = {}) =>
<TouchableOpacity onPress={displayPicker}>
<View style={styles.centerWrap}>
<View style={styles.selectedNumberWrap}>
<Text style={styles.selectedNumberText}>
{value}
</Text>
</View>
</View>
</TouchableOpacity>;
class LYDSelectNumber extends Component {
static propTypes = {
onChangeNumber: PropTypes.func.isRequired,
numbersRange: PropTypes.array,
style: PropTypes.any,
selectedNumberValue: PropTypes.number,
};
static defaultProps = {
numbersRange: [18, 120],
style: undefined,
selectedNumberValue: undefined,
};
render() {
return (
<View style={styles.container}>
<SelectedNumber value={this.props.selectedNumberValue} />
<Picker
style={styles.picker}
selectedValue={this.props.selectedNumberValue}
onValueChange={this.props.onChangeNumber}>
{this._renderNumbers()}
</Picker>
</View>
);
}
_renderNumbers = () => {
const [firstNumber, lastNumber] = this.props.numbersRange;
let numbersItems = [];
let n = firstNumber;
while (n <= lastNumber) {
numbersItems.push(<Item key={n} label={`${n}`} value={n} />);
n++;
}
return numbersItems;
};
}
export default LYDSelectNumber;
const styles = StyleSheet.create({
container: {
flex: 3,
justifyContent: 'center',
alignItems: 'center',
},
picker: {
position: 'absolute',
top: 0,
width: 1000,
height: 1000,
},
centerWrap: {
alignItems: 'center',
},
selectedNumberWrap: {
width: theme.utils.responsiveWidth(40),
paddingBottom: 20,
borderBottomWidth: 2,
alignItems: 'center',
borderBottomColor: theme.colors.darkGranate,
},
selectedNumberText: {
...theme.fontStyles.selectedNumber,
},
});

undefined is not a function (evaluating 'fetch('apiurl')')

I am using below versions
react-native-router-flux ^3.39.1
react-native 0.44.0
I expecting that will call API which I am using with "fetch"
Have used componentDidMount but it's showing another error
undefined is not an object (evaluating 'this._component.getScrollableNode')
But I am getting below error outputs
Steps to reproduce
Create three scene using router flux (In my case App, Login, Home)
Use ScrollView for creating the Login.js Create a button
using TouchableHighlight after that call the fetch with a function
using onPress like onPress={ () => this.fetchData() }
Below code, I am using for App.js
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
AsyncStorage,
} from 'react-native';
import Login from './components/Login'
import Register from './components/Register'
import Home from './components/Home'
import { Scene, Router, TabBar, Modal, Schema, Actions, Reducer, ActionConst } from 'react-native-router-flux'
const reducerCreate = params=>{
const defaultReducer = Reducer(params);
return (state, action)=>{
console.log("ACTION:", action);
return defaultReducer(state, action);
}
};
export default class App extends Component {
constructor(props, context) {
super(props, context);
this.state = {
logged: false,
loading: true,
};
};
componentWillMount(){
self = this;
AsyncStorage.getItem('token')
.then( (value) =>{
if (value != null){
this.setState({
logged: true,
loading: false,
});
}
else {
this.setState({
loading: false,
})
}
});
};
render() {
if (this.state.loading) {
return <View><Text>Loading</Text></View>;
}
return (
<Router>
<Scene hideNavBar={true} key="root">
<Scene key="logIn" component={Login} title="Login" initial={!this.state.logged}/>
<Scene key="regisTer" component={Register} title="Register"/>
<Scene key="home" component={Home} title="home" initial={this.state.logged}/>
</Scene>
</Router>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
And below code, using for Login.js
/* #flow */
import React, { Component } from 'react';
import {
View,
StyleSheet,
Image,
ScrollView,
TextInput,
Text,
TouchableHighlight,
Alert,
} from 'react-native';
import { Container, Content, InputGroup, Input, Icon, Item } from 'native-base';
import Button from 'react-native-button'
import {Actions} from 'react-native-router-flux'
import ResponsiveImage from 'react-native-responsive-image'
export default class Login extends Component {
constructor(props){
super(props)
this.state = {
email: '',
password: '',
data: '',
}
}
fetchData() {
fetch('http://allstariq.tbltechnerds.com/api/login/?username=andress&password=23434')
.then((response) => response.json())
.then((responseData) => {
this.setState({
data: responseData.movies,
});
})
.done();
}
render() {
return (
<View style={styles.container}>
<ScrollView>
<View style={ styles.logoContainer }>
<View style={{flexDirection: 'row',}}>
<ResponsiveImage
source={require('../assets/logo.png')}
initWidth="300"
initHeight="160" />
</View>
</View>
<View style={ styles.formContainer }>
<Item>
<Icon active name='mail' />
<Input
onChangeText={(text) => this.setState({email: text})}
value={this.state.email}
placeholder='Email'/>
</Item>
<Item>
<Icon active name='key' />
<Input
onChangeText={(text) => this.setState({password: text})}
value={this.state.password}
placeholder='Password'/>
</Item>
<TouchableHighlight
style={ styles.loginButton }
onPress={ () => this.fetchData() }>
<Text style={ styles.btnText}>Login</Text>
</TouchableHighlight>
</View>
<View style={ styles.bottomContainer }>
<Text style={ styles.cenText }>Dont worry if you haven't an account yet . . </Text>
<Text
style={ styles.blueText}
onPress={ Actions.regisTer }
>Register Now</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
logoContainer: {
flex: .5,
padding: 10,
justifyContent: 'center',
alignItems: 'center',
},
logoItem: {
width: null,
height: null,
resizeMode: 'cover',
},
formContainer: {
flex: 4,
padding: 10,
},
inputelm: {
marginBottom: 10,
backgroundColor: '#999',
borderWidth: 0,
fontSize: 20,
color: '#FFF',
fontFamily: 'AmaticSC-Bold',
},
loginButton: {
borderRadius: 3,
marginBottom: 20,
marginTop: 20,
paddingLeft: 10,
paddingRight: 10,
backgroundColor: '#2196f3',
elevation: 4,
},
signupButton: {
borderRadius: 3,
marginBottom: 20,
marginTop: 20,
paddingLeft: 10,
paddingRight: 10,
backgroundColor: '#7cb342',
elevation: 4,
},
btnText: {
textAlign: 'center',
color: '#FFF',
fontSize: 30,
lineHeight: 40,
},
blueText: {
textAlign: 'center',
color: '#2196f3',
fontSize: 20,
lineHeight: 40,
},
bottomContainer: {
flex: 1,
padding: 10,
},
cenText: {
textAlign: 'center',
fontSize: 16,
},
});
What is the actual way to use fetch with react-native-router-flux? I am new to react, please help me.
well, its a couple of months late but the problem here is that your fetchData method hasn't got access to this because when you declare a method like this:
fetchData() {
}
Under the hood react is creating a function this way:
this.fetchData = function() {
}
when you declare a function using the function keyword, everything between {} will have its own "this" and your method will not have access to the "this" of the component context.
That is the reason why you are getting the "undefined", because you are calling "this.setState" inside the promise returned by fetch, so the error is not fetch, but this.
To solve this issue you could just define your method this way:
fetchData = () => {
}
And because the functions defined with a fat arrow do not create their own scope, the component "this" will be available from inside your method.
Did you try maybe to import the library?
Import fetch from "fetch";
You have not imported the fetch function, import it from the node-fetch module like
import fetch from 'node-fetch'

Resources