So all the components I am using were created by me excepting TextInput. In another Navigator route i used the all the components excepting TextInput and they worked as intended. But in this case, some how my Buttom positioning follows Card position and not the outer View
// GoalForm.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { Header, Button, Card } from '../components';
import { TextInput } from '#shoutem/ui';
export default class GoalList extends Component {
constructor(props) {
super(props);
}
styles = {
nameGoalContainer: {
flexDirection: 'row'
},
center: {
flexDirection: 'column',
justifyContent: 'center'
},
rightLabels: {
fontWeight: 'bold',
fontSize: 17
}
}
render() {
return (
<View style={{ flex:1 }}>
<Header text="New Goal" color='#3f51b5' />
<Card>
<View style={this.styles.nameGoalContainer}>
<View style={ [this.styles.center, { marginRight: 15 }] }>
<Text style={this.styles.rightLabels}>Title</Text>
</View>
<TextInput
maxLength={30}
placeholder="Buy a new graphics card"
style={{ flex: 3, textAlign: 'center' }}
/>
</View>
</Card>
<Button
text="+"
onPress={ () => { console.log('Hello') } }
size='50'
fontSize='25'
color='#FFD600'
fontColor='white'
style= {{
bottom: 20,
right: 20
}}
/>
</View>
);
}
}
// Card.js
import React, { Component } from 'react';
import { View, Platform } from 'react-native';
class Card extends Component {
constructor(props) {
super(props);
}
generateComponent() {
const { cardStyleAndroid } = this.styles;
const { style } = this.props;
switch (Platform.OS) {
case 'android':
return (
<View style={[ cardStyleAndroid, style ]}>
{ this.props.children }
</View>
);
case 'ios':
return 0;
}
}
render() {
return (
<View>
{ this.generateComponent() }
</View>
);
}
styles = {
cardStyleAndroid: {
elevation: 2,
padding: 10,
backgroundColor: 'white',
marginHorizontal: 10,
marginVertical: 7
}
}
}
Card.propTypes = {
platform: React.PropTypes.string.isRequired,
style: React.PropTypes.object.isRequired,
children: React.PropTypes.object.isRequired
};
export default Card;
// Button.js
import React, { Component } from 'react';
import { View, Platform } from 'react-native';
class Button extends Component {
constructor(props) {
super(props);
}
generateComponent() {
const { cardStyleAndroid } = this.styles;
const { style } = this.props;
switch (Platform.OS) {
case 'android':
return (
<View style={[ cardStyleAndroid, style ]}>
{ this.props.children }
</View>
);
case 'ios':
return 0;
}
}
render() {
return (
<View>
{ this.generateComponent() }
</View>
);
}
styles = {
cardStyleAndroid: {
elevation: 2,
padding: 10,
backgroundColor: 'white',
marginHorizontal: 10,
marginVertical: 7
}
}
}
Button.propTypes = {
platform: React.PropTypes.string.isRequired,
style: React.PropTypes.object.isRequired,
children: React.PropTypes.object.isRequired
};
export default Button;
// Header.js
import React from 'react';
import { View, Text, Platform } from 'react-native';
const generateShadow = () => {
switch(Platform.OS) {
case 'android':
return { elevation: 5 };
case 'ios':
return 0;
}
}
const Header = (props) => {
const { textStyle, viewStyle } = styles;
return (
<View style={ [ viewStyle, { backgroundColor: props.color }, generateShadow() ] }>
<Text style={textStyle}>{ props.text }</Text>
</View>
);
};
Header.propTypes = {
color: React.PropTypes.string.isRequired,
text: React.PropTypes.string.isRequired,
};
const styles = {
textStyle: {
color: 'white',
fontWeight: 'bold',
fontSize: 20
},
viewStyle: {
paddingLeft: 20,
height: 55,
flexDirection: 'column',
justifyContent: 'space-around'
}
};
export default Header;
Can anyone spot what I am missing here? Thanks in advance
I needed to wrap my card component in a View with flex:1
Related
Here in my code I am trying to reload the page on Alert ok button . But its not working . How can I rerender the page on ok button , this is written on same page that I have to reload .
In my code I am sung form and inputfield compont for my login screen . All code is there below . I am tryning to is , when I am getting any respons like wrong username and password in alere then ok button I have to clear my form field . While here ists not happning . For this I am deleting my value mannully.
Please sugget .
import React from 'react';
import { Alert, Dimensions, ImageBackground, Text, View, TouchableOpacity, Platform , StatusBar} from 'react-native';
import Formbox from './ui/form';
import { RegularText, } from './ui/text';
import pkg from '../../package';
import _ from 'lodash';
import { LOGIN_BACKGROUND , LOGIN_BACKGROUND_DARK} from '../images'
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
import parentStyle from '../themes/parent.style'
import LottieView from 'lottie-react-native';
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
const styles = {
imgBG: { width: '100%', height: '100%' },
mainContainer: {
flex: 1,
alignItems: 'stretch',
justifyContent: 'flex-start',
height: deviceHeight,
paddingLeft: 20,
paddingRight: 20
},
logoContainer: { justifyContent: 'center', alignItems: 'center', background: 'red', marginTop: -50 },
logoView: {
borderWidth: 3,
borderColor: '#FFFFFF',
borderRadius: 4,
zIndex: -1,
...Platform.select({
ios: {
shadowOpacity: 0.45,
shadowRadius: 3,
shadowColor: '#090909',
shadowOffset: { height: 1, width: 0 }
},
android: {
elevation: 3
}
})
}
};
export default class Login extends React.Component {
constructor(props) {
super(props);
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (this.props.error) {
if (this.props.error.graphQLErrors[0] !== undefined) {
const errorDetails = _.map(_.split(this.props.error.graphQLErrors[0].message, '#'), _.trim)
const header = errorDetails[0];
const message = errorDetails[1];
Alert.alert(header, message, [{
text: 'OK',
onPress: () => this.props.navigation.push('Auth')
},]);
} else {
Alert.alert('Network Error', this.props.error.networkError.message, [{
text: 'OK',
onPress: () => this.props.navigation.navigate('Auth')
},]);
}
}
}
componentDidMount(){
StatusBar.setBarStyle('dark-content');
}
render() {
let loginForm = [
{ label: 'Username', icon: 'person', type: 'text' },
{ label: 'Password', icon: 'key', type: 'password' }
];
let submitBtn = { label: 'Login', OnSubmit: this.props.onLogin };
let appliedTheme = this.props.theme;
let appliedMode = this.props.mode;
return (
<ImageBackground source={appliedMode === 'light' ? LOGIN_BACKGROUND : LOGIN_BACKGROUND_DARK} style={styles.imgBG}>
<View style={styles.mainContainer}>
<View style={{ flexDirection: 'column', alignContent: 'center', justifyContent: 'center', flex: 1 }}>
<View style={{ flex: 0.75, justifyContent: 'center' }}>
<RegularText text={'Welcome,'} textColor='#57606F' style={{ fontSize: hp('5%') }} />
<RegularText text={'Sign in to continue'} textColor='#ABAFB7' style={{ fontSize: hp('3.5%') }} />
</View>
<View style={{ flex: 2 }}>
<View style={{ flex: 2 }}>
<Formbox
theme={parentStyle[appliedTheme] ? parentStyle[appliedTheme][appliedMode].primaryButtonColor : undefined}
mode={this.props.mode}
formFields={loginForm}
submit={submitBtn}
that={this}
mutation={this.props.token}
/>
<View style={{ height: hp(20), zIndex:10, top: -25}}>
{this.props.loading && (
<LottieView source={require('./animations/login_authentication.json')} autoPlay loop />
)}
</View>
<View style={{top:-70, zIndex:10}}>
{false && <View style={{ alignItems: 'center' }}>
<RegularText text={`v${pkg.version}`} textColor='#ABAFB7' style={{ fontSize: hp('2%') }} />
</View>}
<View style={{ alignItems: 'flex-end' }}>
<View style={{ flexDirection: 'row' }}>
<RegularText text={`New User?`} textColor='#4A494A' style={{ fontSize: hp('2%') }} />
<TouchableOpacity>
<RegularText text={` REGISTER`} textColor={parentStyle[appliedTheme] ? parentStyle[appliedTheme][appliedMode].primaryButtonColor : '#fff'} style={{ fontSize: hp('2%'), fontWeight: 'bold' }} />
</TouchableOpacity>
</View>
</View>
</View>
</View>
</View>
</View>
</View>
</ImageBackground>
);
}
}
////// Form ,js
import React, { Component } from 'react';
import { View, Platform, Dimensions } from 'react-native';
import { PrimaryBtn,PrimaryAbsoluteGradientBtn } from './buttons';
import { InputField, PasswordField } from './inputField';
import { Form } from 'native-base';
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
export default class Formbox extends Component {
constructor(props) {
super(props);
}
OnSubmit() {
let { formFields, that, submit, mutation } = this.props;
submit.OnSubmit.bind(that, formFields, mutation)();
}
OnChange(field, target) {
this.props.formFields.forEach(function (formField, indx) {
if (formField.label === field.label) {
formField.value = target;
}
});
}
renderFields(field, indx) {
let { label, icon, type } = field;
if (label && icon) {
if (type === 'password') {
return <PasswordField key={label + indx} type={type ? type : ''} label={label} icon={icon}
OnChange={this.OnChange} that={this} />;
}
return <InputField key={label + indx} type={type ? type : ''} label={label} icon={icon} OnChange={this.OnChange}
that={this} />;
}
}
render() {
let { formFields, submit, that , theme, mode} = this.props;
return (
<View style={{ width: '100%' }}>
<Form style={{ width: '95%' }}>
{formFields.map((field, indx) => this.renderFields(field, indx))}
<View style={{ marginTop: 60 }}>
<PrimaryAbsoluteGradientBtn label={submit.label} OnClick={this.OnSubmit} that={this} backgroundColor={theme}/></View>
</Form>
</View>
);
}
}
/// input fields js
import React, { Component } from 'react';
import { Icon, Input, Item, Label } from 'native-base';
import { View } from 'react-native';
import { DoNothing } from '../services/services';
class InputField extends Component {
constructor(props) {
super(props);
}
render() {
let { label, OnChange, icon, that,type, keyboardType } = this.props;
return (
<View>
<Item floatingLabel>
{icon && <Icon active name={icon}/>}
{label && <Label>{label}</Label>}
<Input
secureTextEntry={type === 'password'}
onChangeText={OnChange ? (e) => OnChange.bind(that, this.props, e)() : DoNothing.bind(this)}
keyboardType={keyboardType || 'default'}
autoCapitalize = 'none'
autoCorrect={false}
/>
</Item>
</View>
);
}
}
class PasswordField extends Component {
constructor(props) {
super(props);
this.state = {
isMasked: true
};
}
_toggleMask = () => {
this.setState({
isMasked: !this.state.isMasked
});
};
render() {
let { label, OnChange, icon, that, type } = this.props;
const { isMasked } = this.state;
return (
<View>
<Item floatingLabel>
{icon && <Icon active name={icon}/>}
<Label>{label}</Label>
<Input
autoCapitalize = 'none'
secureTextEntry={isMasked}
onChangeText={OnChange ? (e) => OnChange.bind(that, this.props, e)() : DoNothing.bind(this)}
/>
<Icon name={isMasked ? "md-eye-off" : "md-eye"} active type="Ionicons" onPress={() => this._toggleMask()}/>
</Item>
</View>
);
}
}
const styles = {
dark: {
color: "#000000"
},
light: {
color: "#EAEAEA"
}
}
export { InputField, PasswordField };
You can either do :
onPress: () => this.props.navigation.push('Auth')
or do something like :
onPress: () => this.setState({name:'random'})
These both will trigger re rendering, Hope it helps. feel free for doubts
Im trying to create my own react native component when I ran into this problem.
Cannot read property 'containerColor' of undefined
Module AppRegistry is not a registered callable module (calling
runApplication)
I import this component to my app.js where i supply the props. I dont know what else to do.
import React from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import PropTypes from "prop-types";
export default class TreeViewBasic extends React.Component {
constructor(props) {
super();
}
render() {
<View
style={[
Styles.container,
this.props.selected ? Styles.oNBg : Styles.ofFBg
]}
>
<TouchableOpacity onPress={this.props.onPress}>
<View style={{ flex: 1 }}>
<Text style={this.props.selected ? Styles.oNColor : Styles.ofFColor}>
{this.props.name}
</Text>
</View>
</TouchableOpacity>
</View>;
}
}
export const Styles = StyleSheet.create({
container: {
flex: 4, //4 out of 5
elevation: 2,
alignSelf: "flex-end",
height: 40
},
ofFColor: {
color: "darkgray"
},
oNColor: {
color: "black"
},
ofFBg: {
backgroundColor: "gray"
},
oNBg: {
backgroundColor: this.props.containerColor
}
});
TreeViewBasic.defaultProps = {
selected: false,
containerColor: "white"
};
TreeViewBasic.propTypes = {
name: PropTypes.string.isRequired,
onPress: PropTypes.func,
selected: PropTypes.bool,
containerColor: PropTypes.string
};
What is wrong or lacking? Thank you in advance!
You are trying to access props outside of the context. Use StyleSheet.flatten to deal with dynamic styles.
import React from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import PropTypes from "prop-types";
export default class TreeViewBasic extends React.Component {
constructor(props) {
super();
}
render() {
const {containerColor} = this.props;
// dynamic style
const dynamicBG = StyleSheet.flatten([Styles.oNBg, {
backgroundColor: containerColor
}];
<View
style={[
Styles.container,
this.props.selected ? dynamicBG : Styles.ofFBg
]}
>
<TouchableOpacity onPress={this.props.onPress}>
<View style={{ flex: 1 }}>
<Text style={this.props.selected ? Styles.oNColor : Styles.ofFColor}>
{this.props.name}
</Text>
</View>
</TouchableOpacity>
</View>;
}
}
export const Styles = StyleSheet.create({
container: {
flex: 4, //4 out of 5
elevation: 2,
alignSelf: "flex-end",
height: 40
},
ofFColor: {
color: "darkgray"
},
oNColor: {
color: "black"
},
ofFBg: {
backgroundColor: "gray"
},
oNBg: {
backgroundColor: "transparent" // default color
}
});
TreeViewBasic.defaultProps = {
selected: false,
containerColor: "white"
};
TreeViewBasic.propTypes = {
name: PropTypes.string.isRequired,
onPress: PropTypes.func,
selected: PropTypes.bool,
containerColor: PropTypes.string
};
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 }
});
I'm working on a react native application, and using a DrawerNavigator. Unfortunately I'm not able to change the colour of the header, my SideMenu component looks like this:
import React from 'react';
import {
TouchableHighlight,
View,
ScrollView,
Image,
Platform,
StyleSheet
} from 'react-native';
import {NavigationActions} from 'react-navigation';
import {
RkStyleSheet,
RkText,
RkTheme
} from 'react-native-ui-kitten';
import { MainRoutes } from '../routes/routes';
import { MaterialCommunityIcons } from 'react-native-vector-icons';
import { connect } from 'react-redux';
const mapStateToProps = (state) => {
return {
}
}
class SideMenu extends React.Component {
static navigationOptions = ({navigation}) => {
const { state, setParams } = navigation;
return {
headerTintColor: 'red',
headerLeft: null,
headerStyle: { backgroundColor: 'rgba(77, 90, 139, 1)', shadowColor: 'transparent', borderBottomWidth: 0},
};
};
constructor(props) {
super(props);
this._navigateAction = this._navigate.bind(this);
}
_navigate(route) {
let resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({routeName: route.id})
]
});
this.props.navigation.dispatch(resetAction)
}
_renderIcon() {
// if (RkTheme.current.name === 'light')
// return <Image style={styles.icon} source={require('../../assets/images/smallLogo.png')}/>;
// return <Image style={styles.icon} source={require('../../assets/images/smallLogoDark.png')}/>
}
handlePress = (route, index) => {
const { navigation } = this.props;
navigation.navigate(route.id);
}
render() {
let menu = MainRoutes.map((route, index) => {
return (
<TouchableHighlight
style={styles.container}
key={route.id}
underlayColor={RkTheme.current.colors.button.underlay}
activeOpacity={1}
onPress={() => this.handlePress(route, index)}>
<View style={styles.content}>
<View style={styles.content}>
<MaterialCommunityIcons size={25} style={{color: 'white'}} name={route.icon} />
<View style={{flex: 1, alignItems: 'left', paddingLeft: 15}}>
<RkText style={{color:'white'}}>{route.title}</RkText>
</View>
</View>
</View>
</TouchableHighlight>
)
});
return (
<View style={styles.root}>
<ScrollView
showsVerticalScrollIndicator={false}>
<View style={[styles.container, styles.content], {borderTopWidth: 0}}>
{this._renderIcon()}
</View>
{menu}
</ScrollView>
</View>
)
}
}
let styles = RkStyleSheet.create(theme => ({
container: {
height: 80,
paddingHorizontal: 16,
borderTopWidth: StyleSheet.hairlineWidth,
borderColor: 'white',
backgroundColor: 'rgba(77, 90, 139, 1)'
},
root: {
paddingTop: Platform.OS === 'ios' ? 20 : 0,
backgroundColor: 'rgba(77, 90, 139, 1)'
},
content: {
flex: 1,
flexDirection: 'row',
alignItems: 'center'
},
icon: {
marginRight: 13,
}
}));
export default connect(mapStateToProps)(SideMenu);
As you can see I do set the style of the header in the NavigationOptions like I do with the other components but the header stays the same colour.
Could this be because the DrawerNavigator is nested within a TabNavigator?
Thanks and really appreciate any help.
The Navigators are defined as so:
onst SettingsDrawerNavigator = DrawerNavigator(
{
SettingsScreen: {
screen: SettingsScreen
}
},
{
//initialRouteName: 'SettingsScreen',
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
contentComponent: (props) => <SideMenu {...props}/>
}
);
export default TabNavigator(
//Adds elements to the navigator at the bottom.
{
//Other tabs.
Account: {
screen: SettingsDrawerNavigator,
}
},
{
navigationOptions: ({ navigation }) => ({
initialRouteName: 'Home',
tabBarIcon: ({ focused }) => {
const { routeName } = navigation.state;
let iconName;
return (
// <Button badge vertical>
// <Badge ><Text>51</Text></Badge>
<Ionicons
name={iconName}
size={24}
style={{ marginBottom: -3 }}
color={focused ? Colors.tabIconSelected : Colors.tabIconDefault}
/>
// </Button>
);
},
}),
tabBarOptions: {
inactiveBackgroundColor: 'transparent',
activeBackgroundColor: 'transparent',
showLabel: false,
style: {
backgroundColor: '#4d5a8b',
}
},
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}
);
Adding a header to the DrawerNavigator resulted in the following (red). I'm trying to set the white background at the top to red.
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
}
});