How to show how many characters left in redux form render? - react-native

I try to show how many character are left to input in my filed render but I get _this.setState is not a function. (in '_this.setState({value: value})','_this.setState' is undefined)
And here is my render
const renderField = ({ label, keyboardType, name, meta: { touched, error }, input: { onChange, ...restInput } }) => {
this.state = {
value: ''
}
return (
<View style={{ flexDirection: 'column', height: 70, alignItems: 'flex-start' }}>
<View style={{ flexDirection: 'row', alignItems: 'center', borderColor: 'black', borderBottomWidth: 1, }}>
<TextInput style={{ height: 37, width: 295, paddingLeft: 10, fontSize: 20, height: 350, justifyContent: "flex-start" }}
keyboardType={keyboardType} value={this.state.value} onChangeText={(value) => this.setState({ value })} {...restInput}
placeholder={label} numberOfLines={10} multiline={true} maxLength={100}
>
</TextInput>
</View>
<Text>
Characters Left: {this.state.value.length}/100
</Text>
{touched && ((error && <Text style={{ color: 'red', }}>{error}</Text>))}
</View>);
};

You have defined renderField as a functional component, a functional component is stateless by definition. In order to use state all you need to do is change this to class component.
Here is the official link to convert functional component to class component.
Hope this will help!

Related

Unable to Scroll using Flatlist in React native

So i have tried couple of things, data pulled from the REST api works fine without trouble, but when i put it to Flatlist, it does not scroll. Tried countless things I saw on the internet, and still , it does not seem to work.
Below is a snippet i used, to display data from the REST api to the application :
<View>
{isLoading ? <ActivityIndicator/> : <FlatList
style={{fontFamily: 'Poppins-Medium', top: 170, left: 23}}
ItemSeparatorComponent={this.FlatListItemSeparator}
data={transaction_details}
renderItem={({item}) => (
<View style={{paddingTop: 20,flexDirection: 'row', height: 75}}>
<Image source={{uri: item.avatar}} style={{width:50, height:50, borderRadius:25,overflow:'hidden'}}/>
<Text style={styles.PayeeName}>{item.name}{" "}</Text>
<Text style={styles.date_ofTransaction}>{item.date}</Text>
<Text style={styles.amountValue}>{item.amount}</Text>
</View>
)}
keyExtractor={(item) => item.id .toString()}
scrollEnabled={true}
/>}
</View>
Looking over, i saw something like View style={{flex:1}} should I have to try this, the whole thing disappears speedily. I dont know what else I have to try hence, this.
I need help with this.
Thank you!
New Edits
done the edit you asked me to, now there are still some spaces there. Do not know how they came about,
I looks like this now so far
Here is the new Source code
import React, {useEffect, useState} from 'react';
import {
ActivityIndicator,
Image,
ImageBackground,
SafeAreaView,
StyleSheet,
Text,
View,
} from 'react-native';
import {Header, Avatar, Icon, Card} from '#rneui/themed';
import {FlatList, ScrollView} from 'react-native-gesture-handler';
import {Tab} from '#rneui/base';
const HomePage = () => {
const [transaction_details, setTransaction_details] = useState([]);
const[isLoading,setLoading] = useState(true);
const Item = ({title}) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
width: 350,
backgroundColor: '#D3D3D3',
}}
/>
);
};
useEffect(() => {
fetch('https://brotherlike-navies.000webhostapp.com/people/people.php', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
})
.then(response => response.json())
.then(responseJson => {
setTransaction_details(responseJson);
setLoading(false);
});
}, []);
return (
<View style={{flex:1, borderWidth:1}}>
<Header
containerStyle={{
backgroundColor: 'transparent',
justifyContent: 'space-around',
}}
leftComponent={
<Avatar
small
rounded
source={{
uri: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSiRne6FGeaSVKarmINpum5kCuJ-pwRiA9ZT6D4_TTnUVACpNbzwJKBMNdiicFDChdFuYA&usqp=CAU',
}}
onPress={() => console.log('Left Clicked!')}
activeOpacity={0.7}
/>
}
rightComponent={
<Icon
name={'add-circle-outline'}
color={'#00BB23'}
size={32}
onPress={() => console.log('Right Clicked!')}
/>
}></Header>
<View
style={{
flex: 1,
justifyContent: 'center',
borderadius: 9,
alignItems: 'center',
borderWidth:1
}}>
<ImageBackground
source={{
uri: 'asset:/logo/bg.JPG',
}}
imageStyle={{borderRadius: 6}}
style={{
width: 350,
height: 150,
borderadius: 9,
justifyContent: 'center',
alignItems: 'center',
}}>
<View>
<Text style={styles.accText}>Wallet Balance</Text>
<Text style={styles.text}> 250,000 </Text>
</View>
</ImageBackground>
</View>
<View style={{borderWidth:1}}>
<Text
style={{
fontFamily: 'Poppins-Bold',
flexDirection: 'row',
fontSize: 15,
left: 18,
color: 'gray',
}}>
Recent Transactions
</Text>
</View>
<View style={{flex:1, borderWidth:1}}>
{isLoading ? <ActivityIndicator/> : <FlatList
style={{fontFamily: 'Poppins-Medium', left: 23}}
ItemSeparatorComponent={this.FlatListItemSeparator}
data={transaction_details}
renderItem={({item}) => (
<View style={{flex:1,flexDirection: 'row'}}>
<Image source={{uri: item.avatar}} style={{width:50, height:50, borderRadius:25,overflow:'hidden'}}/>
<Text style={styles.PayeeName}>{item.name}{" "}</Text>
<Text style={styles.date_ofTransaction}>{item.date}</Text>
<Text style={styles.amountValue}>{item.amount}</Text>
</View>
)}
keyExtractor={(item) => item.id .toString()}
/>}
</View>
</View>
);
};
export default HomePage;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
date_ofTransaction: {
marginTop: 20,
alignItems:'flex-start',
alignItems:'center',
left: -75,
fontFamily: 'Poppins-Light',
size: 4,
},
paragraph: {
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
padding: 20,
},
text: {
top: -85,
fontSize: 30,
color: 'white',
textAlign: 'center',
fontFamily: 'Poppins-Bold',
},
mainContainer: {
paddingTop: 90,
justifyContent: 'center',
alignItems: 'center',
},
accText: {
top: -85,
paddingTop: 10,
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Poppins-Medium',
color: 'white',
textAlign: 'center',
},
PayeeName: {
justifyContent: 'flex-start',
alignItems:'center',
left: 23,
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight:'bold'
},
amountValue: {
alignItems: 'flex-end',
alignItems:'center',
right: -25,
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight:'bold'
}
});
Method 1
It does not scroll because your view is restricting it. Try replacing view with <></> (Fragments).
Method 2
The other way of solving this is adding flex 1 in view container, it disappears because its parent also needs to be set to flex. So find all parents that have view in it and add flex 1 in them Then it will work

how to use inline flex property in react native

Here's what I'm trying to achieve:
I want to display inline all these three elements inside each Block.
Here's what I have done so far:
export default function App() {
const cheers = [
'cheers',
'high five'
]
return (
<Block style={{ flex: 1,
flexDirection: "row",
alignContent: "space-between",
marginTop: 50}}
>
<Block style={{ flex: 2, justifyContent: 'center'}}>
<Text style={{marginRight: 5}}>Send a</Text>
</Block>
<Block style={[styles.dropdownsRow, {flex: 2}]}>
<SelectDropdownMenu
data={cheers}
onSelect={(selectedItem, index) => {
console.log(selectedItem, index);
}}
defaultButtonText={'Cheers'}
buttonTextAfterSelection={(selectedItem, index) => {
return selectedItem.name;
}}
rowTextForSelection={(item, index) => {
return item.name;
}}
buttonStyle={styles.dropdown1BtnStyle}
buttonTextStyle={styles.dropdown1BtnTxtStyle}
renderDropdownIcon={isOpened => {
return <FontAwesome name={isOpened ? 'chevron-up' : 'chevron-down'} color={'#8898aa'} size={10} />;
}}
dropdownIconPosition={'right'}
dropdownStyle={styles.dropdown1DropdownStyle}
rowStyle={styles.dropdown1RowStyle}
rowTextStyle={styles.dropdown1RowTxtStyle}
/>
</Block>
<Block style={{flex: 2, justifyContent: 'center' }}>
<Text style={{marginLeft: 5, marginRight: 5}}>to</Text>
</Block>
<Block style={{ justifyContent: 'center'}}>
<Input
right placeholder="Type your custom question here."
iconContent={<Block />}
/>
</Block>
);
}
const styles = StyleSheet.create({
dropdownsRow: {justifyContent: 'center', maxWidth: '10%'},
dropdown1BtnStyle: {
height: 45,
backgroundColor: '#edeff2',
borderRadius: 5,
borderColor: '#444',
},
dropdown1BtnTxtStyle: {color: '#8898aa', textAlign: 'left', fontSize: 14},
dropdown1DropdownStyle: {backgroundColor: '#EFEFEF'},
dropdown1RowStyle: {backgroundColor: '#EFEFEF', borderBottomColor: '#C5C5C5'},
dropdown1RowTxtStyle: {color: '#444', textAlign: 'left'}
});
I'm new to react native and don't know how flex property works.
Here's my sample output:
The whole code found here whole code
You can use Yoga layout website to find your desired UI and then migrate your styles to your code.

How can I get this effect in react native?

The radio button must be pair.
How can I make these 4 radio button in one group?
Hey Jin youcheng
You can use the react-native-radio-buttons-group package to implement the radio button group.
Have a look here:
import RadioGroup from 'react-native-radio-buttons-group';
export default class App extends Component {
state = {
data: [
{
label: 'Default value is same as label',
},
{
label: 'Value is different',
value: "I'm not same as label",
},
{
label: 'Color',
color: 'green',
},
{
disabled: true,
label: 'Disabled',
},
{
label: 'Size',
size: 32,
},
],
};
// update state
onPress = data => this.setState({ data });
render() {
let selectedButton = this.state.data.find(e => e.selected == true);
selectedButton = selectedButton ? selectedButton.value : this.state.data[0].label;
return (
<View style={styles.container}>
<Text style={styles.valueText}>
Value = {selectedButton}
</Text>
<RadioGroup radioButtons={this.state.data} onPress={this.onPress} />
</View>
);
}
}
Or something like this
https://github.com/moschan/react-native-simple-radio-button
Hope this will work for you :)
Thanks
If you want to do it without any third party library you can do it by making the layout and using Images of Radio Buttons(one for Selected and one for unselected) inside TouchableOpacity. You can take a variables for button and set them false for initial state. Now once you perform onPress of that particular Radio Button you can set that true. Now you can render Selected Radio Button by using Image source property. Here is the code where I have given background color to Image view as I don't have radio buttons. I also commented the source prop there which you can uncomment and pass the location of the radio buttons according to your condition.
<View style={{height: 200, marginTop:50, width: 220, borderColor: '#000000', borderWidth: 2, alignSelf: 'center'}}>
<View style={{flexDirection:'row', marginTop: 30}} >
<View style={{flexDirection:'row-reverse', width: '50%', height: 50, alignItems: 'center'}}>
<Text style={{marginRight: 5}}>Apple</Text>
<TouchableOpacity
// onPress = {() => this.selectRadioBtn}
>
<Image style={{height: 24, width: 24, backgroundColor: 'steelblue', marginRight: 5}}
// source={require('your_asset_url_her')}
/>
</TouchableOpacity>
</View>
<View style={{flexDirection:'row', width: '50%', height: 50, alignItems: 'center', marginLeft: 5}}>
<TouchableOpacity
// onPress = {() => this.selectRadioBtn}
>
<Image style={{height: 24, width: 24, backgroundColor: 'steelblue', marginRight: 5}}
// source={require('your_asset_url_her')}
/>
</TouchableOpacity>
<Text style={{marginRight: 5}}>Apple</Text>
</View>
</View>
<View style={{flexDirection:'row'}} >
<View style={{flexDirection:'row-reverse', width: '50%', height: 50, alignItems: 'center'}}>
<Text style={{marginRight: 5}}>Apple</Text>
<TouchableOpacity
// onPress = {() => this.selectRadioBtn}
>
<Image style={{height: 24, width: 24, backgroundColor: 'steelblue', marginRight: 5}}
// source={require('your_asset_url_her')}
/>
</TouchableOpacity>
</View>
<View style={{flexDirection:'row', width: '50%', height: 50, alignItems: 'center', marginLeft: 5}}>
<TouchableOpacity
// onPress = {() => this.selectRadioBtn}
>
<Image style={{height: 24, width: 24, backgroundColor: 'steelblue', marginRight: 5}}
// source={require('your_asset_url_her')}
/>
</TouchableOpacity>
<Text style={{marginRight: 5}}>Apple</Text>
</View>
</View>
<TouchableOpacity style={{height: 30, alignSelf: 'center', marginTop: 10, borderColor: '#000000', borderWidth: 2, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{width: 80, alignSelf: 'center', textAlign: 'center'}}>OK</Text>
</TouchableOpacity>
</View>
Please let me know if any clarification required. Thanks :)

Can I use autoGrow in redux form?

I am wondering if I can use autoGrow in redux form or I should use something else?
Here is my render code
const renderField = ({ label, keyboardType, name, meta: { touched, error }, input: {onChange, ...restInput} }) => {
return (
<View style={{flexDirection: 'column', height: 70, alignItems: 'flex-start'}}>
<View style={{flexDirection: 'row', height: 30, alignItems: 'center', borderColor: 'black', borderBottomWidth: 1,}}>
<TextInput style={{ height: 37, width: 280, paddingLeft: 10, fontSize: 20}}
keyboardType={keyboardType} onChangeText={onChange} {...restInput}
placeholder={label}
>
</TextInput>
</View>
{touched && ((error && <Text style={{color: 'red', }}>{error}</Text>))}
</View>);
};
You can use textArea to change the the number of rows and to expand the text area
const renderTextArea = ({ input, label, className, rows, meta: { touched, error, warning }}) => (
<div>
<div>
<textarea {...input} placeholder={label} rows={rows} cols="100" className={className}/>
{touched && ((error && <span className="error_field">{error}</span>) || (warning && <span>{warning}</span>))}
</div>
</div>
)

React-native TouchableOpacity button doesn't respect border/border-radius

I have created a generic button which I'd like to have round edges instead of being a square. My button component is as such:
const Button = ({ onPress, children }) => {
const { buttonStyle, textStyle } = styles;
return (
<TouchableOpacity onPress={onPress} style={buttonStyle}>
<Text style={textStyle}>
{children}
</Text>
</TouchableOpacity>
);
};
const styles = {
textStyle: {
alignSelf: 'center',
color: colors.primaryTeal,
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
paddingBottom: 10,
},
buttonStyle: {
flex: 1,
backgroundColor: colors.whiteText,
marginLeft: 5,
marginRight: 5,
borderRadius: 50
}
};
However, it remains to be square and doesn't respond to borderRadius at all.
It's invoked as such:
<Button onPress={this.onButtonPress.bind(this)}>
Log in
</Button>
How do I make it respect borderRadius and get round edges?
The login form in which it appears(Render)
render() {
return (
<Card>
<CardSection>
<Input
placeholder="user#gmail.com"
label="Email"
value={this.state.email}
onChangeText={email => this.setState({ email })}
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
placeholder="password"
label="Password"
value={this.state.password}
onChangeText={password => this.setState({ password })}
/>
</CardSection>
<View style={styles.btnWrapper}>
<CardSection>
{this.state.loading ?
<Spinner size="small" /> :
<Button onPress={this.onButtonPress.bind(this)}>
Log in
</Button>}
</CardSection>
</View>
<Text style={styles.errorTextStyle} disabled={this.state.error !== null}>
{this.state.error}
</Text>
</Card>
CardSection component:
const CardSection = (props) => {
return (
<View style={styles.containerStyle}>
{props.children}
</View>
);
};
const styles = {
containerStyle: {
borderBottomWidth: 1,
padding: 5,
backgroundColor: '#fff',
justifyContent: 'flex-start',
flexDirection: 'row',
borderColor: '#ddd',
position: 'relative'
}
};
Works perfectly fine. Just make sure to use react native's StyleSheet.create to get cached styles.
Maybe your button container view background is white and you're not seeing the rounded corners.
Heres my working snack
Code snippet i used, but refer to the snack as you'll see it live in action.
import React, { Component } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
const Button = ({ onPress, children }) => {
return (
<TouchableOpacity onPress={onPress} style={styles.buttonStyle}>
<Text style={styles.textStyle}>
{children}
</Text>
</TouchableOpacity>
);
};
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Button>
Log in
</Button>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
backgroundColor: 'black',
},
textStyle: {
alignSelf: 'center',
color: 'teal',
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
paddingBottom: 10,
},
buttonStyle: {
flex: 1,
backgroundColor: 'white',
marginLeft: 5,
marginRight: 5,
borderRadius: 50
},
});
You have to add style overflow: hidden to TouchableOpacity
Try add attribute borderWidth and borderColor on buttonStyle, like below:
buttonStyle: {
backgroundColor: colors.whiteText,
marginLeft: 5,
marginRight: 5,
borderRadius: 50,
borderWidth: 2,
borderColor: "#3b5998"
}
A complete example:
<TouchableOpacity
onPress={() => handleSubmit()}
disabled={!isValid}
style={{
alignSelf: "center",
marginBottom: 30,
overflow: 'hidden',
borderColor: "#3b5998",
borderWidth: 2,
borderRadius: 100,
}}
>
<View
style={{
flexDirection: "row",
alignSelf: "center",
paddingLeft: 15,
paddingRight: 15,
minHeight: 40,
alignItems: 'center',
}}
>
<Text style={{ fontSize: 20, fontWeight: "bold", color: "#3b5998" }}>
SEND
</Text>
</View>
</TouchableOpacity>
I think you might be looking for the containerStyle prop
<TouchableOpacity containerStyle={ViewStyleProps}>