How can I make this custom button component reusable across different controls? - javascript

I have this custom component class that I apply to my React Native Buttons and it has the expected behavior of scaling in and out (adding animation to shrink and resize) which is the behavior I want. However, I want the same animation for other controls in my app like Cards for example. I was wondering, how can I change this class to make it more extensible?
Here's my code:
import React from "react";
import { StyleSheet, Text, TouchableWithoutFeedback, Animated} from "react-native";
import Colors from "./Colors";
import Fonts from "./Fonts";
export default class TouchableBounce extends React.Component {
constructor(props) {
super(props);
this.handlePressIn = this.handlePressIn.bind(this);
this.handlePressOut = this.handlePressOut.bind(this);
}
componentWillMount() {
this.animatedValue = new Animated.Value(1);
}
handlePressIn() {
Animated.spring(this.animatedValue, {
toValue: .5
}).start()
}
handlePressOut() {
Animated.spring(this.animatedValue, {
toValue: 1,
friction: 5,
tension: 40
}).start()
}
render() {
const animatedStyle = {
transform: [{ scale: this.animatedValue}]
}
const {
disabled,
text,
color,
backgroundColor,
style,
showArrow,
testID,
buttonStyle
} = this.props;
return (
<TouchableWithoutFeedback
onPressIn={this.handlePressIn}
onPressOut={this.handlePressOut}
disabled={disabled}
style={[styles.buttonContainer, style]}
testID={testID || `button_${text}`}
>
<Animated.View
style={[
styles.button,
disabled ? { opacity: 0.5 } : {},
{ backgroundColor },
buttonStyle,
animatedStyle
]}
>
<Text style={[styles.buttonText, { color }]}>{text.toUpperCase()}</Text>
{showArrow && (
<Text
style={{
fontSize: 20,
fontWeight: "bold",
color: "white",
fontFamily: "system font",
marginBottom: 1
}}
>
{" "}
→
</Text>
)}
</Animated.View>
</TouchableWithoutFeedback>
);
}
}
TouchableBounce.defaultProps = {
disabled : false,
color : Colors.white,
backgroundColor : Colors.mainAccent,
style : {},
showArrow : false,
testID : "",
buttonStyle : {}
}
const styles = StyleSheet.create({
buttonContainer: {
alignSelf: "stretch",
marginTop: 35,
marginBottom: 35
},
button: {
borderRadius: 4,
padding: 20,
flexDirection: "row",
alignItems: "center",
justifyContent: "center"
},
buttonText: {
textAlign: "center",
fontFamily: Fonts.montserratBold,
fontSize: 16
}
});
EDIT: I have a question on where I should make the change for nesting the component.Inside my Home render function there's this snippet
const card = active ? (
<ActiveCard purchase={active} />
) : (
<InactiveCard />
);
and inside my return of that render, there is this snippet
{!this.props.foo && (
<View>
<TouchableOpacity
testID={"TOUCHABLE_CARD"}
onPress={() => {
this.tapCard(active);
}}
>
{card}
</TouchableOpacity>
</View>
)}
Where should I wrap the TouchableBounce? In both places or one of those places?

Try passing them as children of TouchableBounce
<TouchableBounce>
<CardView/>
</TouchableBounce>
In the TouchableBounce render them as
<TouchableWithoutFeedback
onPressIn={this.handlePressIn}
onPressOut={this.handlePressOut}
disabled={disabled}
style={[styles.buttonContainer, style]}
testID={testID || `button_${text}`}
>
<Animated.View
style={[
styles.button,
disabled ? { opacity: 0.5 } : {},
{ backgroundColor },
buttonStyle,
animatedStyle
]}
>
{this.props.children}//Here is the cardview that you have sent
</Animated.View>
</TouchableWithoutFeedback>
Edit:
For clear understanding iam attaching a working demo Expo demo
and also the official docs React.Children

Related

tabBarOptions not applied to project (React Native)

I am creating a small app that has a to-do list and a calendar. At the bottom is a bottom tab navigator. Everything works and is functional, however, when I try to add style: {} inside tabBarOptions it isn't being applied. Changing activeTintColor, inactiveTintColor and labelStyle works just fine.
I tried to create a stylesheet and replace everything inside tabBarOptions, but that didn't work. My main goal is to simply create a slightly larger bar along the bottom of the screen. I don't even want a crazy custom navigation bar, just slightly larger so I can make the items inside a little bigger.
MainContainer Class:
import React from 'react';
import {StyleSheet} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import Ionicons from 'react-native-vector-icons/Ionicons'
//screens
import Calendar from './screens/Calendar';
import ToDoList from './screens/ToDoList';
// Screen names
const calendarName = 'Calendar';
const ToDoListName = 'To Do List';
const Tab = createBottomTabNavigator();
export default function MainContainer() {
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'black',
labelStyle: {paddingBottom: 10, fontSize: 10},
style: {padding: 10, height: 70},
}}
initialRouteName={ToDoListName}
screenOptions={({route}) => ({
tabBarIcon: ({focused, color, size}) => {
let iconName;
let rn = route.name;
if (rn === ToDoListName) {
iconName = focused ? 'list' : 'list-outline'; //icons in package. Change later.
} else if (rn === calendarName) {
iconName = focused ? 'calendar' : 'calendar-outline'
}
return <Ionicons name={iconName} size={size} color={color}/>
},
})}>
<Tab.Screen name={ToDoListName} component={ToDoList}/>
<Tab.Screen name={calendarName} component={Calendar}/>
</Tab.Navigator>
</NavigationContainer>
)
}
For reference here is my ToDoList class
import { KeyboardAvoidingView, StyleSheet, Text, View, TextInput, TouchableOpacity, Platform, Keyboard } from 'react-native';
import Task from '../../components/Task';
import React, { useState } from 'react';
import { ScrollView } from 'react-native-web';
export default function ToDoList() {
const [task, setTask] = useState();
const [taskItems, setTaskItems] = useState([]);
const handleAddTask = () => {
Keyboard.dismiss();
setTaskItems([...taskItems, task])
setTask(null);
}
const completeTask = (index) => {
let itemsCopy = [...taskItems];
itemsCopy.splice(index, 1);
setTaskItems(itemsCopy)
}
return (
<View style={styles.container}>
{/* Scroll View when list gets longer than page */}
<ScrollView contentContainerStyle={{
flexGrow: 1
}} keyboardShouldPersistTaps='handled'>
{/*Today's Tasks */}
<View style={styles.tasksWrapper}>
<Text style={styles.sectionTitle}>Today's Tasks</Text>
<View style={styles.items}>
{/* This is where the tasks will go*/}
{
taskItems.map((item, index) => {
return (
<TouchableOpacity key={index} onPress={() => completeTask(index)}>
<Task text={item} />
</TouchableOpacity>
)
})
}
</View>
</View>
</ScrollView>
{/* Write a task section */}
{/* Uses a keyboard avoiding view which ensures the keyboard does not cover the items on screen */}
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.writeTaskWrapper}>
<TextInput style={styles.input} placeholder={'Write a task'} value={task} onChangeText={text => setTask(text)} />
<TouchableOpacity onPress={() => handleAddTask()}>
<View style={styles.addWrapper}>
<Text style={styles.addText}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#E8EAED',
},
tasksWrapper: {
paddingTop: 20,
paddingHorizontal: 20,
},
sectionTitle: {
fontSize: 24,
fontWeight: 'bold',
},
items: {
marginTop: 30,
},
writeTaskWrapper: {
position: 'absolute',
bottom: 20,
paddingLeft: 10,
paddingRight: 10,
width: '100%',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
},
input: {
paddingVertical: 15,
width: 250,
paddingHorizontal: 15,
backgroundColor: '#FFF',
borderRadius: 60,
borderColor: '#C0C0C0',
borderWidth: 1,
},
addWrapper: {
width: 60,
height: 60,
backgroundColor: '#FFF',
borderRadius: 60,
justifyContent: 'center',
alignItems: 'center',
borderColor: '#C0C0C0',
borderWidth: 1,
},
addText: {
},
});
And my Calendar class
import * as React from 'react';
import { View, Text } from 'react-native';
export default function Calendar(){
return(
<View>
<Text>Calendar Will go here</Text>
</View>
)
}
I made a Task component for the ToDoList. Not sure if you need it to solve this but I'll paste it here anyway.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { TouchableOpacity } from 'react-native-web';
const Task = (props) => {
return (
<View style={styles.item}>
<View style={styles.itemLeft}>
<View style={styles.square}></View>
<Text style={styles.itemText}>{props.text}</Text>
</View>
<View style={styles.circular}></View>
</View>
)
}
const styles = StyleSheet.create({
item: {
backgroundColor: '#FFF',
padding: 15,
borderRadius: 10,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 20,
},
itemLeft: {
flexDirection: 'row',
alignItems: 'center',
flexWrap: 'wrap',
},
square: {
width: 24,
height: 24,
backgroundColor: '#55BCF6',
opacity: .4,
borderRadius: 5,
marginRight: 15,
},
itemText: {
maxWidth: '80%',
},
circular: {
width: 12,
height: 12,
borderColor: '#55BCF6',
borderWidth: 2,
borderRadius: 5
},
});
export default Task;
It sounds like you are looking for the tabBarStyle property. You should be able to rename style (which is not a supported prop of the tab navigator) to tabBarStyle.
Here's the spot in the docs that mentions this. https://reactnavigation.org/docs/bottom-tab-navigator#tabbarstyle
What I ended up doing to solve this was to put the styling inside the screenOptions. I didn't want to do this because I wanted to separate the styling from the logic, but it solved the problem for me. See code below:
export default function MainContainer() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName={ToDoListName}
screenOptions={({route}) => ({
tabBarIcon: ({focused, color, size}) => {
let iconName;
let rn = route.name;
if (rn === ToDoListName) {
iconName = focused ? 'list' : 'list-outline'; //icons in package. Change later.
} else if (rn === calendarName) {
iconName = focused ? 'calendar' : 'calendar-outline'
}
return <Ionicons name={iconName} size={size} color={color}/>
},
activeTintColor: 'tomato',
inactiveTintColor: 'black',
tabBarShowLabel: false,
tabBarStyle: {padding: 10, height: 100, backgroundColor: 'black'},
})}>
<Tab.Screen name={ToDoListName} component={ToDoList}/>
<Tab.Screen name={calendarName} component={Calendar}/>
</Tab.Navigator>
</NavigationContainer>
)
}

Improving React Native performance deactivating Component when not in use

I'm developing an app for tuning pianos in react-native. I have an App.js and some screens implemented with react-navigation. The question is, how i can deactivate (or just not render) a component Screen when the user isn't in that screen?
The idea is to catch when this Screen Component is the Active Screen (like using navigation props), i can activate the render and deactivate when the Active Screen changes.
The Tab.js, containing the tab screens.
import React from "react";
/** Screens */
import TunerScreen from "./tunerScreen";
import Inharmonicity from "./inharmonicityScreen";
import BeatsScreen from "./beatsScreen";
/** Navigation */
import { MaterialCommunityIcons } from "#expo/vector-icons";
import { createMaterialBottomTabNavigator } from "#react-navigation/material-bottom-tabs";
/** Tab */
const Tab = createMaterialBottomTabNavigator();
/* Tabs of screen */
export default Tabs = ({
handleSwitch,
beatsCalc,
inharmonicityCalc,
inharmonicitySave,
}) => {
return (
<Tab.Navigator activeColor="#000" barStyle={{ backgroundColor: "white" }}>
<Tab.Screen
...
/>
// This is the component screen trying to deactivate
<Tab.Screen
name="Beats"
children={() => (
<BeatsScreen beatsCalc={beatsCalc} />
)}
options={{
tabBarLabel: "Beats",
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="blur-radial"
color="black"
size={26}
/>
),
}}
/>
<Tab.Screen
...
/>
</Tab.Navigator>
);
};
The BeatsScreen.js (component to deactivate).
import React, { Component, useState } from "react";
import { View, Text, Button, Switch } from "react-native";
import Note from "../src/components/note";
import { connect } from "react-redux";
import style from "../styles/style";
import Picker from "#gregfrench/react-native-wheel-picker";
var PickerItem = Picker.Item;
class BeatsScreen extends Component {
constructor(props) {
super(props);
this.state = {
beats: 0,
// Prima nota
firstNote: { name: "A", octave: 4, frequency: 440, selected: false },
// Seconda nota
secondNote: { name: "A", octave: 4, frequency: 440, selected: false },
// Elemento selezionato dal picker
selectedItem: 0,
// Elementi del picker
itemList: ["Terza", "Quarta", "Quinta", "Ottava", "Prima"],
};
}
beatsUpdate = () => {
this.state.beats = beatsCalc(
this.state.firstNote,
this.state.secondNote,
this.state.selectedItem
);
};
render() {
if (!this.state.firstNote.selected)
this.state.firstNote = this.props.note;
if (!this.state.secondNote.selected)
this.state.secondNote = this.props.note;
this.beatsUpdate();
return (
<View style={{ flex: 1, flexDirection: "column" }}>
<View style={{ flex: 1 }}>
<View style={{ flex: 1, flexDirection: "row" }}>
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Note {...this.state.firstNote} />
<Text style={style.frequency}>
{this.state.firstNote.frequency.toFixed(1)} Hz
</Text>
{
<Switch
style={{
paddingTop: 50,
transform: [{ scaleX: 2 }, { scaleY: 2 }],
}}
value={this.state.firstNote.selected}
onValueChange={() => {
// Se la nota è stata selezionata
this.state.firstNote.selected =
!this.state.firstNote.selected;
}}
/>
}
</View>
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Note {...this.state.secondNote} />
<Text style={style.frequency}>
{this.state.secondNote.frequency.toFixed(1)} Hz
</Text>
<Switch
style={{
paddingTop: 50,
transform: [{ scaleX: 2 }, { scaleY: 2 }],
}}
value={this.state.secondNote.selected}
onValueChange={() => {
// Se la nota è stata selezionata
this.state.secondNote.selected =
!this.state.secondNote.selected;
}}
/>
</View>
</View>
</View>
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Picker
style={{ width: 150, height: 180 }}
lineColor="#000000" //to set top and bottom line color (Without gradients)
lineGradientColorFrom="#008000" //to set top and bottom starting gradient line color
lineGradientColorTo="#FF5733" //to set top and bottom ending gradient
selectedValue={this.state.selectedItem}
itemStyle={{ color: "black", fontSize: 26 }}
onValueChange={(index) => {
this.state.selectedItem = index;
this.beatsUpdate();
}}
>
{this.state.itemList.map((value, i) => (
<PickerItem label={value} value={i} key={i} />
))}
</Picker>
<Text style={{ fontSize: 18 }}>Battimenti: </Text>
<Text style={{ fontSize: 80, paddingTop: 1 }}>
{this.state.beats}
</Text>
</View>
</View>
);
}
}
/** Mappa lo stato (store) con le props, cosi' da poterle usare nel componente. */
const mapStateToProps = (state) => {
const { note } = state;
const { tunerSwitch } = state;
return { note, tunerSwitch };
};
const mapDispatchToProps = (dispatch) => {
return {
startAndStop: () => dispatch({ type: "SWITCH" }),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(BeatsScreen);
I think if you use this option on the init of the tab bar you could solve your issue https://reactnavigation.org/docs/bottom-tab-navigator/#detachinactivescreens

react-native paper button vector-icons float right

I try to build an accordeonmenu with chevron icons my headerbutton has following code:
const AccordeonHeader = (Props) => {
return(
<View style={[accordionStyles.header]}>
<Button
contentStyle={[accordionStyles.header__button, ]}
color='black'
onPress={() => {show !== Props.value ? setShow(Props.value) : setShow(false)}}
>
<Text
style={[accordionStyles.header__text, styles.headline__h2]}
>
{Props.label}
</Text>
<Icon
iconStyle={[accordionStyles.header__icon,]}
name={show === Props.value ? "chevron-up" : "chevron-down"}
>
</Icon>
</Button>
</View>
);
}
with this styles
const accordionStyles = StyleSheet.create({
header: {
},
header__button: {
width:'100%',
borderColor:'green',
borderWidth:2,
flexDirection:'row',
justifyContent:'space-between',
},
header__text: {
display:'none',
color:'black',
},
header__icon: {
alignSelf:'flex-end',
color:'black',
},
});
but i can't get the icon on the rigth side and the text stay on the left.
its alwayse directly beside.
Update
import * as React from 'react';
import { Text, View, StyleSheet ,Button,TouchableOpacity} from 'react-native';
import Constants from 'expo-constants';
import FontAwesome from "react-native-vector-icons/FontAwesome";
export default function App() {
return (
<TouchableOpacity style={[accordionStyles.header]} onPress={()=>console.log("press")}>
<Text style={{paddingTop:5}}>Sortieren</Text>
<FontAwesome
iconStyle={[accordionStyles.header__icon]}
size={30}
color="#000000"
name={"chevron-up"}
/>
</TouchableOpacity>
);
}
const accordionStyles = StyleSheet.create({
header: {
width: "100%",
borderColor: "green",
borderWidth: 2,
flexDirection: "row",
justifyContent: "space-between"},
header__icon: {
alignSelf: "flex-end",
color: "black"
}
});
Code on snack
its Very Simple just add ,
contentStyle={{flexDirection: 'row-reverse'}}
and our icon moves to right side

How to rerender the page on alert ok button

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

React Native Text color not working

I've got a Text component inside a TouchableOpacity which I want to change the color depend on a var.
Here is my code:
import React, { Component } from "react";
import { StyleSheet, Text, View, TouchableOpacity } from "react-native";
var flag = false;
export default class MyTest extends Component {
changeColor() {
flag = true;
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={{ flex: 1, backgroundColor: "#888888", margin: 20 }}
onPress={this.changeColor.bind(this)}
>
<Text style={[{ color: "blue" }, flag ? { color: "red" } : false]}>
One
</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "#F5FCFF"
}
});
I have tried to use this.state.textColor but no result. I've also tried to use that in styles variable but again, not working.
Any idea?
The flag variable is not in your component state, so the component will not re-render when it changes.
Put it in your component state instead and toggle it with setState and it will work.
class MyTest extends Component {
state = { flag: true };
changeColor = () => {
this.setState(previousState => {
return { flag: !previousState.flag };
});
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={{ flex: 1, backgroundColor: "#888888", margin: 20 }}
onPress={this.changeColor}
>
<Text style={{ color: this.state.flag ? "red" : "blue" }}>One</Text>
</TouchableOpacity>
</View>
);
}
}
You have to give style to the Text for color.
<Text style={styles.steelblue}>Sign Up</Text>
Give this style to Text.
const styles = StyleSheet.create({
steelblue: {
color: "steelblue",
},
});
try this example this may help you to solve problem.
import React, { Component } from 'react';
import { Platform, StyleSheet, View, Text } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={[styles.setFontSize,styles.setColorRed]}> React Native Font example 1</Text>
<Text style={[styles.setFontSize,styles.setColorPink]}> React Native Font example 2</Text>
<Text style={[styles.setFontSize,styles.setColorPurple]}> React Native Font example 3</Text>
<Text style={[styles.setFontSize,styles.setColorBlue]}> React Native Font example 4</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
setFontSize: {
fontSize: 20,
fontWeight : 'bold'
},
setColorRed : {
color: '#f44336'
},
setColorPink :{
color: '#e91e63'
},
setColorPurple :{
color: '#9c27b0'
},
setColorBlue :{
color: '#2196f3'
},
});

Categories

Resources