Why isn't the props/actions passed the first time? - javascript

I have a list of "comparators" that I can choose from. I want to show the amounts of accounts in one comparator just under the title.
I was able to make a function that fetch the accounts and get the size. However, it only works the second time I load the page. If I load it for the first time, the results always show 0.
How can I make sure that the the first time I load the page, the data is fetched and loading correctly?
Here is my code:
import React, {Component} from 'react';
import {TouchableOpacity, Image, StyleSheet, View} from 'react-native';
import {HardbaconText} from '../components';
import colors from '../../src/res/colors/index';
import next from '../../src/res/images/files/comparators/next.png';
import I18n from '../i18n/i18n';
import {connect} from 'react-redux';
import * as actions from '../actions';
export class ComparatorOption extends Component {
constructor(props) {
super(props);
this.state = {amount: 0};
}
componentDidMount() {
this.props.getAmount(this.props.type);
}
render() {
return (
<TouchableOpacity
style={styles.option}
onPress={(props, ref) => {
this.props.navigation.navigate(this.props.destination);
}}>
<View style={styles.leftSide}>
<Image
style={styles.image}
resizeMode={'contain'}
source={this.props.img}
/>
<View style={styles.textContainer}>
<HardbaconText style={styles.title}>
{I18n.t(this.props.type)}
</HardbaconText>
<HardbaconText style={styles.subtitle}>
{`${(this.props.amount && this.props.amount[this.props.type]) ||
'0'} ${I18n.t('products')}`}
</HardbaconText>
</View>
</View>
<View style={styles.nextContainer}>
<Image source={next} style={styles.next} resizeMethod="contain" />
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
option: {
marginHorizontal: 10,
backgroundColor: 'white',
borderRadius: 10,
height: 80,
padding: 10,
marginTop: 15,
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
image: {
width: 25,
height: '100%',
marginRight: 20,
marginLeft: 20,
},
leftSide: {
display: 'flex',
flexDirection: 'row',
},
textContainer: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
},
title: {
fontSize: 14,
fontWeight: '700',
color: 'black',
},
subtitle: {
fontSize: 9,
color: colors.hardbaconDarkGray,
},
nextContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
next: {
height: 24,
opacity: 0.3,
},
});
const mapStateToProps = ({comparators}) => {
return {
amount: comparators.accountsAmount,
};
};
export default connect(
mapStateToProps,
actions,
)(ComparatorOption);
import {
SET_COMPARATOR_PRODUCTS_AMOUNT,
GET_COMPARATORS_INSTITUTIONS,
GET_COMPARATOR_ACCOUNTS,
} from '../types/Comparators';
import Config from 'react-native-config';
import {AxiosInstance} from '../api/AxiosInstance';
export const getAmount = comparator => dispatch => {
AxiosInstance.get('/comparators/' + comparator, {
headers: {
'X-Comparator-API-KEY': Config.COMPARATOR_API_KEY,
'content-type': 'application/json',
},
}).then(res => {
dispatch({
type: SET_COMPARATOR_PRODUCTS_AMOUNT,
payload: {
comparator: comparator,
amount: res.data.length,
},
});
});
};
import {
SET_COMPARATOR_PRODUCTS_AMOUNT,
GET_COMPARATORS_INSTITUTIONS,
GET_COMPARATOR_ACCOUNTS,
} from '../types/Comparators';
const INITIAL_STATE = {
accountsAmount: {},
institutions: [],
accounts: [],
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case SET_COMPARATOR_PRODUCTS_AMOUNT:
var accountsAmount = state.accountsAmount;
accountsAmount[action.payload.comparator] = action.payload.amount;
return Object.assign({}, state, {accountsAmount: accountsAmount});
case GET_COMPARATORS_INSTITUTIONS:
return {
...state,
institutions: action.payload,
};
case GET_COMPARATOR_ACCOUNTS:
return {
...state,
accounts: action.payload,
};
default:
return state;
}
};

Could be because you mutating state try the following instead:
case SET_COMPARATOR_PRODUCTS_AMOUNT:
//make a shallow copy
var accountsAmount = {...state.accountsAmount};
//mutate the shallow copy
accountsAmount[action.payload.comparator] =
action.payload.amount;
return Object.assign({}, state, {
accountsAmount,
});

Related

react native push values to array

I have a simple react-native. where I ma tracking user location and pushing that into array to draw a simple line. but when I try to push values it give me this error
TypeError: cannot add a new property, js engine: hermes
here is my code and I shared all the three case. I also tried many of the stackoverflow questions but none of this working. it was working 3 to 4 days earlier. it day 3 I am working on this but non of the case is working. sometime its start working but values or not pushing. means array is already empty. case 4 is the only screen and it works fine
CASE 1
import React, {useEffect} from 'react';
import {Alert, StyleSheet, TouchableOpacity, View} from 'react-native';
import Geolocation from 'react-native-geolocation-service';
import {moderateScale} from 'react-native-size-matters';
import Entypo from 'react-native-vector-icons/Entypo';
import {MainRoutes} from '../constants/Routes';
import colors from '../constants/theme';
const GpsTrackerScreen = ({navigation}) => {
let location_route = [];
useEffect(() => {
watchPosition();
}, []);
const watchPosition = () => {
try {
const watchID = Geolocation.watchPosition(
position => {
let coords = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
};
location_route.push(coords);
},
error => Alert.alert('WatchPosition Error', JSON.stringify(error)),
);
} catch (error) {
Alert.alert('WatchPosition Error', JSON.stringify(error));
}
};
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => navigation.navigate(MainRoutes.TrackHistoryScreen)}
style={styles.HistoryButton}>
<Entypo name={'back-in-time'} color={'#fff'} size={moderateScale(30)} />
</TouchableOpacity>
</View>
);
};
export default GpsTrackerScreen;
const styles = StyleSheet.create({
container: {flex: 1, backgroundColor: colors.white, alignItems: 'center'},
HistoryButton: {
width: moderateScale(50),
position: 'absolute',
top: 20,
right: 20,
zIndex: 200,
alignSelf: 'center',
height: moderateScale(50),
justifyContent: 'center',
paddingHorizontal: moderateScale(10),
alignItems: 'center',
elevation: 5,
borderRadius: moderateScale(50),
backgroundColor: colors.primaryColor,
},
});
CASE 2:
import React, {useEffect, useState} from 'react';
import {Alert, StyleSheet, TouchableOpacity, View} from 'react-native';
import Geolocation from 'react-native-geolocation-service';
import {moderateScale} from 'react-native-size-matters';
import Entypo from 'react-native-vector-icons/Entypo';
import fonts from '../constants/fonts';
import {MainRoutes} from '../constants/Routes';
import {SCREEN_WIDTH} from '../constants/scaling';
import colors from '../constants/theme';
const GpsTrackerScreen = ({navigation}) => {
const [location_route, setLocationRoute] = useState([]);
useEffect(() => {
watchPosition();
}, []);
const watchPosition = () => {
try {
const watchID = Geolocation.watchPosition(
position => {
let coords = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
};
let temp_route = [...location_route];
temp_route.push(coords);
setLocationRoute(temp_route);
},
error => Alert.alert('WatchPosition Error', JSON.stringify(error)),
);
} catch (error) {
Alert.alert('WatchPosition Error', JSON.stringify(error));
}
};
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => navigation.navigate(MainRoutes.TrackHistoryScreen)}
style={styles.HistoryButton}>
<Entypo name={'back-in-time'} color={'#fff'} size={moderateScale(30)} />
</TouchableOpacity>
</View>
);
};
export default GpsTrackerScreen;
const styles = StyleSheet.create({
container: {flex: 1, backgroundColor: colors.white, alignItems: 'center'},
HistoryButton: {
width: moderateScale(50),
position: 'absolute',
top: 20,
right: 20,
zIndex: 200,
alignSelf: 'center',
height: moderateScale(50),
justifyContent: 'center',
paddingHorizontal: moderateScale(10),
alignItems: 'center',
elevation: 5,
borderRadius: moderateScale(50),
backgroundColor: colors.primaryColor,
},
});
CASE 3:
import React, {useEffect} from 'react';
import {Alert, StyleSheet, TouchableOpacity, View} from 'react-native';
import Geolocation from 'react-native-geolocation-service';
import {moderateScale} from 'react-native-size-matters';
import Entypo from 'react-native-vector-icons/Entypo';
import {MainRoutes} from '../constants/Routes';
import colors from '../constants/theme';
let location_route = [];
const GpsTrackerScreen = ({navigation}) => {
useEffect(() => {
watchPosition();
}, []);
const watchPosition = () => {
try {
const watchID = Geolocation.watchPosition(
position => {
let coords = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
};
location_route.push(coords);
},
error => Alert.alert('WatchPosition Error', JSON.stringify(error)),
);
} catch (error) {
Alert.alert('WatchPosition Error', JSON.stringify(error));
}
};
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => navigation.navigate(MainRoutes.TrackHistoryScreen)}
style={styles.HistoryButton}>
<Entypo name={'back-in-time'} color={'#fff'} size={moderateScale(30)} />
</TouchableOpacity>
</View>
);
};
export default GpsTrackerScreen;
const styles = StyleSheet.create({
container: {flex: 1, backgroundColor: colors.white, alignItems: 'center'},
HistoryButton: {
width: moderateScale(50),
position: 'absolute',
top: 20,
right: 20,
zIndex: 200,
alignSelf: 'center',
height: moderateScale(50),
justifyContent: 'center',
paddingHorizontal: moderateScale(10),
alignItems: 'center',
elevation: 5,
borderRadius: moderateScale(50),
backgroundColor: colors.primaryColor,
},
});
CASE 4:
import React, {useEffect, useState} from 'react';
import {Alert, StyleSheet, TouchableOpacity, View} from 'react-native';
import Geolocation from 'react-native-geolocation-service';
import {moderateScale} from 'react-native-size-matters';
import SplashScreen from 'react-native-splash-screen';
import Entypo from 'react-native-vector-icons/Entypo';
const GpsTrackerScreen = ({navigation}) => {
let location_route = [];
const [watchid, setWatchId] = useState(null);
SplashScreen.hide();
const clearwatch = () => {
Geolocation.clearWatch(watchid);
};
const watchPosition = () => {
try {
const watchID = Geolocation.watchPosition(
position => {
let coords = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
};
location_route.push(coords);
console.log(location_route, 'location_route');
},
error => Alert.alert('WatchPosition Error', JSON.stringify(error)),
{
accuracy: {
android: 'high',
ios: 'best',
},
enableHighAccuracy: false,
timeout: 15000,
maximumAge: 10000,
distanceFilter: 0,
forceRequestLocation: true,
forceLocationManager: true,
showLocationDialog: true,
},
);
setWatchId(watchID);
} catch (error) {
Alert.alert('WatchPosition Error', JSON.stringify(error));
}
};
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => watchPosition()}
style={styles.HistoryButton}>
<Entypo name={'back-in-time'} color={'#fff'} size={moderateScale(30)} />
</TouchableOpacity>
<TouchableOpacity
onPress={() => clearwatch()}
style={styles.HistoryButton}>
<Entypo name={'back-in-time'} color={'#fff'} size={moderateScale(30)} />
</TouchableOpacity>
</View>
);
};
export default GpsTrackerScreen;
const styles = StyleSheet.create({
container: {flex: 1, backgroundColor: '#fff', alignItems: 'center'},
HistoryButton: {
width: moderateScale(50),
zIndex: 200,
alignSelf: 'center',
height: moderateScale(50),
justifyContent: 'center',
paddingHorizontal: moderateScale(10),
alignItems: 'center',
elevation: 5,
margin: 100,
borderRadius: moderateScale(50),
backgroundColor: 'green',
},
});

How to show error message on react native using redux

i am using redux in my react native app .
my problem is how to show the error message that appear in the terminal to the render .
i tried to use {this.props.error} and nothing will show up
Actions
import * as actionTypes from "./Types";
export const setErrors = errors => ({
type: actionTypes.SET_ERRORS,
payload: errors
});
export const resetError = () => {
return async dispatch => {
dispatch({
type: actionTypes.RESET_ERROR,
payload: []
});
};
};
Reducers
import * as actionTypes from "../actions/Types";
import { SET_ERRORS, RESET_ERROR } from "../actions/Types";
const initialState = {
errors: [],
reset: ""
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case SET_ERRORS:
console.log("from reducer");
console.log("errrrro", action.payload);
return {
...state,
errors: Object.keys(action.payload).map(
key => `${key}: ${action.payload[key]}`
)
};
case RESET_ERROR:
return {
...state,
errors: action.payload
};
default:
return state;
}
};
export default reducer;
this is my index.js
import React, { Component } from "react";
import { connect } from "react-redux";
import * as actionCreators from "../../store/actions";
import {
StyleSheet,
Text,
View,
TextInput,
Button,
TouchableHighlight,
Image
} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
class Login extends Component {
state = {
username: "",
password: ""
};
resetState = () => {
this.setState({ password: null });
};
errors = () => {
this.props.errors;
};
Login = () => {
this.props.login(this.state, this.props.navigation);
this.resetState();
};
render() {
return (
<LinearGradient
colors={["#002d44", "#001724"]}
style={{ flex: 1 }}
start={[0, 0]}
end={[1, 0]}
>
<View style={styles.container}>
<Text>{error}</Text>
<View style={styles.inputContainer}>
<Image
style={styles.inputIcon}
source={{
uri:
"https://img.icons8.com/ios/80/000000/identification-documents-filled.png"
}}
/>
<TextInput
style={styles.inputs}
autoCapitalize="none"
placeholder="اسم المستخدم"
onChangeText={username => this.setState({ username })}
value={this.state.username}
/>
</View>
<View style={styles.inputContainer}>
<Image
style={styles.inputIcon}
source={{
uri: "https://img.icons8.com/ios/80/000000/lock-2-filled.png"
}}
/>
<TextInput
style={styles.inputs}
placeholder="كلمة المرور"
secureTextEntry={true}
onChangeText={password => this.setState({ password })}
value={this.state.password}
/>
</View>
<TouchableHighlight
style={[styles.buttonContainer, styles.loginButton]}
onPress={this.Login}
>
<Text style={{ color: "#fff", fontSize: 15 }}>دخول</Text>
</TouchableHighlight>
<TouchableHighlight
style={{}}
onPress={() => this.props.navigation.replace("Signup")}
>
<Text style={{ color: "#00F7EA", fontSize: 15 }}>تسجيل</Text>
</TouchableHighlight>
</View>
</LinearGradient>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
inputContainer: {
borderBottomColor: "#F5FCFF",
backgroundColor: "#FFFFFF",
borderRadius: 30,
borderBottomWidth: 1,
width: 250,
height: 45,
marginBottom: 20,
flexDirection: "row",
alignItems: "center"
},
inputs: {
height: 45,
marginLeft: 16,
fontSize: 15,
textAlign: "center",
borderBottomColor: "#FFFFFF",
flex: 1
},
inputIcon: {
width: 30,
height: 30,
marginLeft: 15,
justifyContent: "center"
},
buttonContainer: {
height: 45,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginBottom: 20,
width: 250,
borderRadius: 30,
borderWidth: 0.8,
borderColor: "#d6d7da"
},
loginButton: {
backgroundColor: "transparent"
},
buttonDisabled: {
backgroundColor: "#e7e7e7"
},
loginText: {
color: "white"
}
});
const mapStateToProps = state => ({
user: state.authReducer.user,
loading: state.devicesReducer.loading,
errors: state.errorReducer.errors
});
const mapDispatchToProps = dispatch => ({
login: (userData, navigation) =>
dispatch(actionCreators.login(userData, navigation)),
checkForExpiredToken: navigation =>
dispatch(actionCreators.checkForExpiredToken(navigation))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Login);
the error message that showing on the terminal
from reducer
errrrro Object {
"password": Array [
"This field may not be blank.",
],
"username": Array [
"This field may not be blank.",
],
}
from reducer
errrrro [Error: Request failed with status code 400]

How to solve the problem for stackNavigator

Here In this code I am populating json data on ListView ..and after click item value, passing that particular value on new screen.. .
I have created MainActivity where I am populating JSON value and on SecondActivity sendng selected item value ,
To navigate between class I am using
export default MyNewProject = StackNavigator(
{
First: { screen: MainActivity },
Second: { screen: SecondActivity }
});
// getting error "undefined is not a function (evaluating '(0 _reactnavigation.stacknavigator)')"..
import React, { Component } from 'react';
import { StyleSheet, Text, View, ListView, ActivityIndicator } from 'react-native';
import { StackNavigator } from 'react-navigation';
class MainActivity extends Component {
constructor(props) {
super(props);
this.state = {
// Default Value of this State.
Loading_Activity_Indicator: true
}
}
componentDidMount() {
return fetch('https://reactnativecode.000webhostapp.com/FruitsList.php')
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
Loading_Activity_Indicator: false,
dataSource: ds.cloneWithRows(responseJson),
}, function() {
// In this block you can do something with new state.
});
})
.catch((errorMsg) => {
console.error(errorMsg);
});
}
ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
Navigate_To_Second_Activity=(fruit_name)=>
{
//Sending the JSON ListView Selected Item Value On Next Activity.
this.props.navigation.navigate('Second', { JSON_ListView_Clicked_Item: fruit_name });
}
static navigationOptions =
{
title: 'MainActivity',
};
render()
{
if (this.state.Loading_Activity_Indicator) {
return (
<View style={styles.ActivityIndicator_Style}>
<ActivityIndicator size = "large" color="#009688"/>
</View>
);
}
return (
<View style={styles.MainContainer}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={(rowData) => <Text style={styles.rowViewContainer}
onPress={this.Navigate_To_Second_Activity.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>}
/>
</View>
);
}
}
class SecondActivity extends Component
{
static navigationOptions =
{
title: 'SecondActivity',
};
render()
{
return(
<View style = { styles.MainContainer }>
<Text style = { styles.TextStyle }> { this.props.navigation.state.params.JSON_ListView_Clicked_Item } </Text>
</View>
);
}
}
export default MyNewProject = StackNavigator(
{
First: { screen: MainActivity },
Second: { screen: SecondActivity }
});
const styles = StyleSheet.create(
{
MainContainer:
{
justifyContent: 'center',
flex:1,
margin: 10
},
TextStyle:
{
fontSize: 23,
textAlign: 'center',
color: '#000',
},
rowViewContainer:
{
fontSize: 17,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
},
ActivityIndicator_Style:
{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
left: 0,
right: 0,
top: 0,
bottom: 0,
}
});
// I have tried may thing but not getting the solutions .. I am stuck , this might be small thing but not getting the solutions..
I need help for this ..
Thanks
Try this code
import React, { Component } from 'react';
import { StyleSheet, Text, View, ListView, ActivityIndicator } from 'react-native';
import { createStackNavigator } from 'react-navigation'
class MainActivity extends Component {
constructor(props) {
super(props);
this.state = {
// Default Value of this State.
Loading_Activity_Indicator: true
}
}
componentDidMount() {
return fetch('https://reactnativecode.000webhostapp.com/FruitsList.php')
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
Loading_Activity_Indicator: false,
dataSource: ds.cloneWithRows(responseJson),
}, function() {
// In this block you can do something with new state.
});
})
.catch((errorMsg) => {
console.error(errorMsg);
});
}
ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
Navigate_To_Second_Activity=(fruit_name)=>
{
//Sending the JSON ListView Selected Item Value On Next Activity.
this.props.navigation.navigate('Second', { JSON_ListView_Clicked_Item: fruit_name });
}
static navigationOptions =
{
title: 'MainActivity',
};
render()
{
if (this.state.Loading_Activity_Indicator) {
return (
<View style={styles.ActivityIndicator_Style}>
<ActivityIndicator size = "large" color="#009688"/>
</View>
);
}
return (
<View style={styles.MainContainer}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={(rowData) => <Text style={styles.rowViewContainer}
onPress={this.Navigate_To_Second_Activity.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>}
/>
</View>
);
}
}
class SecondActivity extends Component
{
static navigationOptions =
{
title: 'SecondActivity',
};
render()
{
return(
<View style = { styles.MainContainer }>
<Text style = { styles.TextStyle }> { this.props.navigation.state.params.JSON_ListView_Clicked_Item } </Text>
</View>
);
}
}
export default MyNewProject = createStackNavigator (
{
First: { screen: MainActivity },
Second: { screen: SecondActivity }
});
const styles = StyleSheet.create(
{
MainContainer:
{
justifyContent: 'center',
flex:1,
margin: 10
},
TextStyle:
{
fontSize: 23,
textAlign: 'center',
color: '#000',
},
rowViewContainer:
{
fontSize: 17,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
},
ActivityIndicator_Style:
{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
left: 0,
right: 0,
top: 0,
bottom: 0,
}
});
Change your code to this.
import { createStackNavigator } from 'react-navigation';
export default MyNewProject = createStackNavigator(
{
First: { screen: MainActivity },
Second: { screen: SecondActivity }
});
stackNavigator is deprecated, you should use createStackNavigator instead
More info at: https://reactnavigation.org/docs/en/stack-navigator.html
EDIT:
import { createStackNavigator } from 'react-navigation'
export default MyNewProject = createStackNavigator (
{
First: { screen: MainActivity },
Second: { screen: SecondActivity }
});

Adding background image to create-react-native project

I am trying to insert a background image into my create-react-native project. I would like to be able to add this image: https://i.pinimg.com/736x/80/29/a9/8029a9bf324c79b4803e1e5a2aba25f3--costume-makeup-iphone-wallpaper.jpg. I have tried applying it to the stylesheet but it is not accepting the background-image tag. I am very new at react.
import React from 'react';
import { StyleSheet, Text, View, TextInput, Button} from 'react-native';
import ListItem from "/Users/Westin/assignment5/ListItem";
export default class App extends React.Component {
state ={
thing: "",
things: [],
};
thingValueChanged = value =>{
//alert(value);
this.setState({
thing: value
});
}
onClickingAdd = () =>
{
if(this.state.thing === "")
{
return;
}
this.setState(prevState => {
return {
things: prevState.things.concat(prevState.thing)
};
});
}
render() {
const thingsOut = this.state.things.map((thing,i) => (<ListItem key = {i} thing={thing} />))
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>My Favourite Things</Text>
</View>
<View style={styles.input}>
<TextInput
value={this.state.thing}
placeholder="Add your favourite things"
style={styles.inputbox}
onChangeText={this.thingValueChanged}
/>
<Button
title="Add"
style={styles.addButton}
onPress = {this.onClickingAdd}
/>
</View>
<View>
{thingsOut}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#e6eeff',
alignItems: 'center',
justifyContent: 'flex-start',
paddingTop: 30,
},
header: {
padding: 10,
},
headerText: {
fontSize: 30,
color: '#003cb3',
},
inputbox: {
borderWidth: 1,
height: 40,
width: "70%",
},
addButton: {
width: "30%"
},
input: {
flexDirection: "row",
width: '100%',
justifyContent: "space-evenly",
alignItems: "center",
}
});
This is the code I tried to run
import React from 'react';
import { StyleSheet, Text, View, TextInput, Button, Image } from 'react-native';
import ListItem from "/Users/Westin/assignment5/ListItem";
const remote = 'https://i.pinimg.com/736x/80/29/a9/8029a9bf324c79b4803e1e5a2aba25f3--costume-makeup-iphone-wallpaper.jpg';
export default class BackgroundImage extends Component {
render() {
const resizeMode = 'center';
return (
<Image
style={{
flex: 1,
resizeMode,
}}
source={{ uri: remote }}
/>
);
}
}
AppRegistry.registerComponent('BackgroundImage', () => BackgroundImage);
export default class App extends React.Component {
state ={
thing: "",
things: [],
};
thingValueChanged = value =>{
//alert(value);
this.setState({
thing: value
});
}
onClickingAdd = () =>
{
if(this.state.thing === "")
{
return;
}
this.setState(prevState => {
return {
things: prevState.things.concat(prevState.thing)
};
});
}
render() {
const thingsOut = this.state.things.map((thing,i) => (<ListItem key = {i} thing={thing} />))
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>My Favourite Things</Text>
</View>
<View style={styles.input}>
<TextInput
value={this.state.thing}
placeholder="Add your favourite things"
style={styles.inputbox}
onChangeText={this.thingValueChanged}
/>
<Button
title="Add"
style={styles.addButton}
onPress = {this.onClickingAdd}
/>
</View>
<View>
{thingsOut}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
backgroundColor: 'black',
opacity: 0.5,
justifyContent: 'flex-start',
paddingTop: 30,
},
header: {
padding: 10,
},
headerText: {
fontSize: 30,
color: '#003cb3',
},
inputbox: {
borderWidth: 1,
height: 40,
width: "70%",
backgroundColor: 'white',
},
addButton: {
width: "30%"
},
input: {
flexDirection: "row",
width: '100%',
justifyContent: "space-evenly",
alignItems: "center",
}
});
It said I cant run two export classes
This code works for me:
import React from 'react';
import { StyleSheet, Text, View, ImageBackground } from 'react-native';
export default class App extends React.Component {
render() {
return (
<ImageBackground source=
{ {uri: 'https://i.pinimg.com/736x/80/29/a9/8029a9bf324c79b4803e1e5a2aba25f3--costume-makeup-iphone-wallpaper.jpg' } }
style={styles.container}
>
<Text>Some</Text>
<Text>Text</Text>
<Text>Centered</Text>
<Text>In</Text>
<Text>Columns</Text>
</ImageBackground>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
width: '100%'
},
});
You can read more about <ImageBackground/> here: https://facebook.github.io/react-native/docs/images#background-image-via-nesting

React Native randomly errors: Can't find variable image after 30 - 90 seconds

So I'm building a React Native app using
React Native - Latest
MobX and MobX-React - Latest
Firebase - Latest
My app works fine. However, I can leave the app idle or play around with it and after 30-90 seconds I red screen with this error. Its not being very specific about what file is erroring! How can I debug this?
Firebase.js
export function getFeed(db,id,callback){
db.collection("posts").where("userId", "==", id)
.get()
.then(function (querySnapshot) {
callback(true,querySnapshot)
})
.catch(function (error) {
callback(false)
console.log("Error getting documents: ", error);
});
}
List.js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableOpacity,
FlatList,
ActivityIndicator,
RefreshControl
} from 'react-native';
import Post from './Post';
import Spinner from 'react-native-spinkit';
import { Icon } from 'react-native-elements';
import { getFeed } from '../../network/Firebase';
import { observer, inject } from 'mobx-react';
#inject('mainStore')
#observer export default class List extends Component {
constructor(props) {
super(props)
this.state = {
dataSource: [],
initialLoad: true,
refreshing: false
}
this.getData = this.getData.bind(this)
}
componentWillMount() {
this.getData()
}
getData() {
this.setState({
refreshing: true
})
getFeed(this.props.screenProps.db, this.props.mainStore.userData.id, (status, res) => {
let tempArray = []
let counter = 0
res.forEach((doc) => {
let tempObj = doc.data()
doc.data().user
.get()
.then((querySnapshot) => {
tempObj.userData = querySnapshot.data()
tempArray.push(tempObj)
counter = counter + 1
if (counter === res.docs.length - 1) {
this.setState({
dataSource: tempArray,
initialLoad: false,
refreshing: false
})
}
})
});
})
}
renderRow = ({ item }) => {
return (
<Post item={item} />
)
}
render() {
if (this.state.initialLoad) {
return (
<View style={styles.spinner}>
<Spinner isVisible={true} type="9CubeGrid" size={40} color="white" />
</View>
)
} else {
return (
<FlatList
data={this.state.dataSource}
extraData={this.state}
keyExtractor={(_, i) => i}
renderItem={(item) => this.renderRow(item)}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this.getData}
/>
}
/>
);
}
}
}
const styles = StyleSheet.create({
spinner: {
marginTop: 30,
alignItems: 'center'
}
});
Post.js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableOpacity,
Image
} from 'react-native';
import moment from 'moment';
import { Icon } from 'react-native-elements';
export default class Post extends React.PureComponent {
render() {
let today = moment()
let date = this.props.item.date
if(today.diff(date, 'days') < 5){
date = moment(date).startOf('day').fromNow()
}else{
date = moment(date).format('DD MMM YYYY, h:mm a')
}
return (
<View
style={styles.container}
>
<View style={styles.top}>
<Image style={styles.profile} source={{uri: this.props.item.userData.image}} />
<Text style={styles.title}>{this.props.item.userData.firstName+' '+this.props.item.userData.lastName}</Text>
</View>
<View style={styles.descriptionContainer}>
<Text style={styles.description}>{this.props.item.description}</Text>
</View>
<View style={styles.imageContainer}>
<Image style={styles.image} source={{uri: this.props.item.image}} />
</View>
<TouchableOpacity style={styles.commentsContainer}>
<View style={styles.timeFlex}>
<Text style={styles.title}>{date}</Text>
</View>
<View style={styles.commentFlex}>
<Text style={styles.title}>Comments (12)</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
title: {
color: 'white',
backgroundColor: 'transparent'
},
timeFlex: {
flex: 0.5,
alignItems: 'flex-start'
},
commentFlex: {
flex: 0.5,
alignItems: 'flex-end'
},
profile: {
width: 40,
height: 40,
borderRadius: 20,
marginRight: 10
},
descriptionContainer: {
marginBottom: 10,
marginHorizontal: 15,
},
description: {
color: 'rgba(255,255,255,0.5)'
},
commentsContainer: {
marginBottom: 10,
alignItems: 'flex-end',
marginHorizontal: 15,
flexDirection: 'row'
},
imageContainer: {
marginBottom: 10,
marginHorizontal: 15,
height: 180
},
image: {
height: '100%',
width: '100%'
},
top: {
justifyContent: 'flex-start',
margin: 10,
marginLeft: 15,
flexDirection: 'row',
alignItems: 'center'
},
container: {
margin: 10,
backgroundColor: '#243c5e',
borderRadius: 10,
shadowColor: 'black',
shadowOffset: {
width: 2,
height: 1
},
shadowRadius: 4,
shadowOpacity: 0.3
}
});

Categories

Resources