React Native how to pass the value from component to the main activity without using Redux? - react-native

I am making a upload product for selling .
And I had make a component for receive the input number(units or price) from the user,
and in the main page will need to count the total price : units * price ..
However ,I get stucked here ... I don't know how I am able to get the value from the component ..
I have attached my code . Could you please take a look ? Thank you so much !!
Component for putting number
import React from 'react';
import { StyleSheet, View } from 'react-native'
import { TextInput } from 'react-native-gesture-handler';
import colors from '../config/colors';
function TryInputNum({children}) {
return (
<View style={styles.container}>
<TextInput placeholder="Enter a number">{children}</TextInput>
</View>
);
}
const styles = StyleSheet.create({
container :{
width : 150,
height : 200,
backgroundColor : colors.white,
}
})
export default TryInputNum;
The main page
import React from 'react';
import { StyleSheet, View,Text } from 'react-native'
import TryInputNum from '../components/TryInputNum';
import colors from '../config/colors';
function TryCountScreen({children}) {
return (
<View style={styles.container}>
<Text>{children}</Text>
<TryInputNum/>
</View>
);
}
const styles = StyleSheet.create({
container : {
flex :1,
backgroundColor : colors.primary,
justifyContent : 'center',
alignItems : 'center',
}
})
export default TryCountScreen;

You can pass onChangeText function from the children and access it as a prop inside the main component. In the onChangeText you can return the text value from the TextInput component and handle it inside the main component. It would like like this
function TryInputNum({children,onChangeText}) {
return (
<View style={styles.container}>
<TextInput onChangeText={value => onChangeText(value)} placeholder="Enter a
number">{children}</TextInput>
</View>
);
}
and then deal with the value from the main screen like this
import React from 'react';
import { StyleSheet, View,Text } from 'react-native'
import TryInputNum from '../components/TryInputNum';
import colors from '../config/colors';
function TryCountScreen({children}) {
return (
<View style={styles.container}>
<Text>{children}</Text>
//Here you have access to that text value thats written inside the
// TextInput component
<TryInputNum onChangeText={text => console.log(text)}/>
</View>
);
}
const styles = StyleSheet.create({
container : {
flex :1,
backgroundColor : colors.primary,
justifyContent : 'center',
alignItems : 'center',
}
})
export default TryCountScreen;

Related

Problem with lining up contents: react native

I'm currently having a problem with the clickable size of a reusable button which includes an icon and text. When I run this code it seems like the entire row becomes clickable when I only want the icon and text to become clickable. Does anyone know how to solve this problem? Thanks
App.js
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import IconTextButton from './components/iconTextButton';
export default function App() {
return (
<View style={styles.container}>
<Text style={{marginTop: 100}}>My First React App! Sike </Text>
<IconTextButton iconFont="ionicons" iconName="pencil" iconSize={25} text="Add Items"/>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'powderblue',
},
});
iconTextButton.js
import React from 'react';
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native';
import Ionicon from 'react-native-vector-icons/Ionicons';
export default function IconTextButton({ iconFont, iconName, iconSize, text, onPress }) {
const getIconFont = (iconFont) => {
switch (iconFont) {
case "ionicons":
return Ionicon;
}
};
const FontIcon = getIconFont(iconFont);
return (
<TouchableOpacity onPress={onPress} style={styles(iconSize).container>
<FontIcon name={iconName} size={iconSize} style={styles(iconSize).buttonIcon}>
<Text style={styles(iconSize).buttonText}>{text}</Text>
</FontIcon>
</TouchableOpacity>
)
}
const styles = (size) => StyleSheet.create({
container: {
backgroundColor: 'pink',
},
buttonIcon: {
backgroundColor: 'yellow',
width: size,
},
buttonText: {
backgroundColor: 'green'
},
})
Along with the code I've tried, I've also tried to keep and as seperate contents whilst adding a flexDirection: 'row' inside styles.container. This keeps the contents in the same line but it still makes the whole row clickable. I've also tried putting everything in a and moving the styles.container to the component and adding a height: size into styles.container. This makes the clickable component limited however, the component is hidden underneath due to the restricted height. I have also tried simply just using instead of making a reusable const that its an input. The same thing applies.
You can wrap your Icon and Text Component in a View component and then wrap it inside a TouchableOpacity Component
Try this or do something like this :
import React from 'react';
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native';
import Ionicon from 'react-native-vector-icons/Ionicons';
export default function IconTextButton({ iconFont, iconName, iconSize, text, onPress }) {
const getIconFont = (iconFont) => {
switch (iconFont) {
case "ionicons":
return Ionicon;
}
};
const FontIcon = getIconFont(iconFont);
return (
<TouchableOpacity onPress={onPress} style={styles(iconSize).container}>
<View style={styles(iconSize).iconTextContainer}>
<FontIcon name={iconName} size={iconSize} style={styles(iconSize).buttonIcon} />
<Text style={styles(iconSize).buttonText}>{text}</Text>
</View>
</TouchableOpacity>
)
}
const styles = (size) => StyleSheet.create({
container: {
backgroundColor: 'pink',
},
iconTextContainer: {
flexDirection: 'row',
alignItems: 'center',
},
buttonIcon: {
backgroundColor: 'yellow',
width: size,
},
buttonText: {
backgroundColor: 'green'
},
})

React Native element only visible/usable after pressing a button

New to React Native, having a go at an app idea. Basically I'm just trying to create an TextInput element that appears when I press a Button. Below is my attempt. I'm trying to take advantage of state within my class, but something is off.
Expo is throwing an error of 'null is not an object (evaluating 'this.state.isShowingText')'.
Any ideas?
import React, { Component } from 'react';
import { TextInput, Alert, Button, ScrollView, Text, View, StyleSheet } from 'react-native';
export default class CoolComponent extends Component {
render() {
const nameAdd = () =>{
state = { isShowingText: true };
}
return (
<View style={{ alignItems: 'center', top: 50 }}>
<Title>Some Title</Title>
{this.state.isShowingText ? <TextInput></TextInput> : null}
<ScrollView></ScrollView>
<Button
title="Press me"
onPress={nameAdd}
/>
</View>
);
}
}
The way you handling state is wrong
import React, { Component } from 'react';
import { TextInput, Button, ScrollView, View } from 'react-native';
export default class CoolComponent extends Component {
state = {
isShowingText: false
}
nameAdd = () => {
this.setState({
isShowingText: true
})
}
render() {
return (
<View style={{ alignItems: 'center', top: 50 }}>
{this.state.isShowingText ? <TextInput style={{ width: '50', height: '50', borderWidth: 1 }}></TextInput> : null}
<ScrollView></ScrollView>
<Button
title="Press me"
onPress={this.nameAdd}
/>
</View>
);
}
}
Hope this helps you. Feel free for doubts.

How to modify a component's property in a function?

I'm trying to learn react and how to use third party components, what I'm trying to do now is to use the component that I installed from https://www.npmjs.com/package/react-native-countdown-component
objective:
The Countdown component has a "Props" called "running" which I would like to modify when I "click" on the component.
code:
the code that I'm using is just a fresh new app created using "expo init MyApp", then I've pasted in the code to import and generate the component
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
// https://www.npmjs.com/package/react-native-countdown-component
import CountDown from 'react-native-countdown-component';
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<CountDown
until={60}
size={30}
//onFinish={() => alert('Finished')}
digitStyle={{backgroundColor: '#FFF'}}
digitTxtStyle={{color: '#1CC625'}}
timeToShow={['M', 'S']}
timeLabels={{m: '', s: ''}}
showSeparator={true}
onPress={() =>
{
this.setState({running:true});
}}
running={false}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
what is the correct way to modify the "running" property of the Countdown component when the component is clicked?
You can start using state properly. For this time I will use React Hooks, it's simpler than using the traditional functional or class components. See more
Every time state is updated, it will cause component to rerender with the new value.
import React, { useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
// https://www.npmjs.com/package/react-native-countdown-component
import CountDown from 'react-native-countdown-component';
export default function App() {
const [isRunning, setRunning] = useState(false) //React Hooks
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<CountDown
until={60}
size={30}
//onFinish={() => alert('Finished')}
digitStyle={{backgroundColor: '#FFF'}}
digitTxtStyle={{color: '#1CC625'}}
timeToShow={['M', 'S']}
timeLabels={{m: '', s: ''}}
showSeparator={true}
//When component is pressed, updates state to true
onPress={() => { setRunning(true); }}
running={isRunning}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I found another way, that requires a new class but I prefer Ian Steban Vasco's answer.
the solution that I found out was to create a new component that will hold the "state" for the Countdown component, then use the MyCountdown component in the main method instead of directly using the Countdown component
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
// https://www.npmjs.com/package/react-native-countdown-component
import CountDown from 'react-native-countdown-component';
export default class MyCountdown extends React.Component{
state = {
running: false
};
handleOnPress = () =>{
this.setState({running:!this.state.running});
}
render(){
return (
<CountDown
until={60}
size={30}
//onFinish={() => alert('Finished')}
digitStyle={{backgroundColor: '#FFF'}}
digitTxtStyle={{color: '#1CC625'}}
timeToShow={['M', 'S']}
timeLabels={{m: '', s: ''}}
showSeparator={true}
onPress={this.handleOnPress}
running={this.state.running}
/>
);
}
}

textAlign justify property not working in react native

I have try to use textAlign: 'justify' property in react native.TextAlign justify doesn't work on Android.
React native version: "react-native": "0.59.5"
import React from 'react';
import { Image, View } from 'react-native';
import { Text, Button } from 'native-base';
import { connect } from 'react-redux';
import EStyleSheet from 'react-native-extended-stylesheet';
import { colors } from '../styles';
class Login extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.contentCenter}>
<Text style={[styles.titleContent,styles.fontBold]}>Simple Secure</Text>
<Text style={[styles.titleContent,styles.fontBold]}>Reliable Messaging</Text>
</View>
</View>
);
}
}
const styles = EStyleSheet.create({
titleContent: {
color:'#62778c',
fontSize: '1.4rem',
textAlign: 'justify',
}
});
const mapStateToProps = (state) => {
return {};
};
export default connect(mapStateToProps)(Login);
checkout the offical document:
textAlign: enum('auto', 'left', 'right', 'center', 'justify')
Specifies text alignment. The value 'justify' is only supported on iOS and fallbacks to left on Android.
As mentioned above android does not support text justification but you can go around this by adding the html text inside WebView like this:
<WebView
source={{ html: "<p style='text-align:justify;'>Your justified text</p>" }}
/>

Styling custom component in react native

I am trying to add styling to my custom component in react native, but no matter what I do, the style has no effect. Here is my code:
// App.js
import MyCustomComponent from './components/myCustomComponent.js';
render() {
return (
<View style={styles.container}>
<MyCustomComponent style={{marginTop: 10}}/>
</View>
);
}
The project compiles fine, and my custom component appears on screen fine, but the marginTop styling is not applied. It is worth noting that the style for the parent View component does apply correctly. This is a brand new project I just created today. This seems like it should be extremely basic, but just isn't working. What can I do to apply this styling?
Custom component code:
import React, {Component} from 'react';
import {TextInput, StyleSheet, Image, View, Button} from 'react-native';
type Props = {};
export default class MyCustomComponent extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Image
source={{ uri: "source here" }}
style={{ width: 50, height: 50 }}
/>
<TextInput
style={{ height: 50 }}
placeholder="Search"
/>
</View>
)
}
}
you can use this code:
export default class MyCustomComponent extends Component<Props> {
render() {
return (
<View style={[styles.container, {...this.props.style}]}>
...
</View>
)
}
}
now, styles.container is applied and anything you pass to component through style will be added to component style.
I hope this can help you
You can apply a style to your custom component by passing style as props.
and
Use it as style={this.props.style} in your MyCustomComponent.
import React, {Component} from 'react';
import {TextInput, StyleSheet, Image, View, Button} from 'react-native';
type Props = {};
export default class MyCustomComponent extends Component<Props> {
render() {
return (
<View style={[styles.container,{...this.props.style}]}>//<--Use like this---
<Image
source={{ uri: "source here" }}
style={{ width: 50, height: 50 }}
/>
<TextInput
style={{ height: 50 }}
placeholder="Search"
/>
</View>
)
}
}
add this code in your CustomText.js file (custom component):
import React from 'react'
import {Text, StyleSheet} from 'react-native'
const CustomText = props => {
return (<Text {...props} style={{...styles.text, ...props.style}}>{props.children}</Text>);
}
export default CustomText;
const styles = StyleSheet.create({
text:{
color: '#000'
}
})
and use in the file:
<CustomText style={styles.text}>My text</CustomText>
const styles = StyleSheet.create({
text:{
fontSize: 20,
}
});
this code merge styles and pass all property to the custom components.
For example, lets change background color of custom card.
Custom Card:
export default function MyCard({color}) {
return (
<View style={[styles.card, {backgroundColor: color}]}>
</View>
)
}
In another file
<MyCard color={"pink"} />
Here, styles.card is the style added in Custom Card file and the color is given during component use.
Note: MyCard({color}) if you miss to add highlight parentheses, it will not work. I faced this issue.
You need to apply this style yourself inside MyCystomComponent. For example:
const MyCustomComponent = ({style}) => (
<View style={style}> // This will be the style that is passed as a prop.
</View>
);