I am trying to display my formik form, this is the first time I am using this. The screen however is completely blank. I think it has something to do with my styling however I'm not sure. Here is my code:
export default class Checkout extends Component {
render() {
return (
<View style={styles.container}>
<Formik
initialValues={{first_name: '', last_name: ''}}
onSubmit={(values) => {
console.log(values);
}}>
{(props) => {
<View>
<TextInput
style={styles.input}
placeholder="first name"
onChangeText={props.handleChange('first_name')}
value={props.values.first_name}
/>
<TextInput
style={styles.input}
placeholder="last name"
onChangeText={props.handleChange('last_name')}
value={props.values.last_name}
/>
<Button
title="place order"
color="maroon"
onPress={props.handleSubmit}
/>
</View>;
}}
</Formik>
</View>
);
}
}
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderColor: 'black',
padding: 10,
fontSize: 18,
borderRadius: 6,
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Since you are using {} then you should return something like this
<Formik
initialValues={{first_name: '', last_name: ''}}
onSubmit={(values) => {
console.log(values);
}}>
{(props) => {return (<View ...} }
or you can remove these {} inside Formik and then no need to type a return statement as you are returning only one thing. Here's what you should do
export default class Checkout extends Component {
render() {
return (
<View style={styles.container}>
<Formik
initialValues={{first_name: '', last_name: ''}}
onSubmit={(values) => {
console.log(values);
}}>
{(props) =>
<View>
<TextInput
style={styles.input}
placeholder="first name"
onChangeText={props.handleChange('first_name')}
value={props.values.first_name}
/>
<TextInput
style={styles.input}
placeholder="last name"
onChangeText={props.handleChange('last_name')}
value={props.values.last_name}
/>
<Button
title="place order"
color="maroon"
onPress={props.handleSubmit}
/>
</View>;
}
</Formik>
</View>
);
}
}
Related
I'm allowing the user to select a number from picker it can by any no like 1,4,6 random. When he selects a number like 3 then 3 TextInputs will be shown and he will enter something in 3 input fields and I want to save these values into an array. How can do this in react native
I think I'm using a bad approach and I want someone expert who can make my code efficient and tell me how can I store values into an array.Regards
{this.state.noOfStores === 1 && (
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
)}
{this.state.noOfStores === 2 && (
<View>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
</View>
)}
{this.state.noOfStores === 3 && (
<View>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
</View>
)}
{this.state.noOfStores === 4 && (
<View>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
<TextInput
style={[
styles.input,
{
backgroundColor: theme.colors.lightGray,
},
]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
/>
</View>
)}
Use this I hope it'll solve your problem.
If you need any assist in following code let me know.
import React, {Component} from 'react';
import {View, TouchableOpacity, Text, TextInput} from 'react-native';
export class AddInputs extends Component {
state = {
textInput: [],
inputData: [],
};
//function to add TextInput dynamically
addTextInput = index => {
let textInput = this.state.textInput;
textInput.push(
<TextInput
style={{
height: 40,
width: '100%',
borderColor: '#2B90D8',
borderBottomWidth: 3,
}}
placeholder={'Add Text'}
onChangeText={text => this.addValues(text, index)}
/>,
);
this.setState({textInput});
};
//function to add text from TextInputs into single array
addValues = (text, index) => {
let dataArray = this.state.inputData;
let checkBool = false;
if (dataArray.length !== 0) {
dataArray.forEach(value => {
if (value.index === index) {
value.text = text;
checkBool = true;
}
});
}
if (checkBool) {
this.setState({
inputData: dataArray,
});
} else {
dataArray.push({text: text, index: index});
this.setState({
inputData: dataArray,
});
}
};
render() {
return (
<View
style={{
flex: 1,
}}>
<View
style={{
width: '100%',
alignItems: 'center',
}}>
{this.state.textInput.map(value => {
return value;
})}
</View>
<TouchableOpacity
onPress={() => {
this.addTextInput(
'your desired number of inputs here like 5, 20 etc',
);
}}>
<Text>Add Inputs</Text>
</TouchableOpacity>
</View>
);
}
}
You can something like below, setting an array with a given length based on your picker and showing the UI based on that.
The setRows sets the number of rows and you can update the array easily.
Call the setRows from your picker.
export default function App() {
const [textArr, setTextArr] = useState([]);
const onChangeText = (text, index) => {
const arr = [...textArr];
arr[index] = text;
setTextArr(arr);
};
const setRows=(rowCount)=>{
setTextArr(Array(rowCount).fill('Default text'))
};
return (
<View style={{ paddingTop: 100 }}>
<Button
title="set"
onPress={()=>setRows(6)}
/>
{textArr.map((item, index) => (
<TextInput
style={[styles.input, { backgroundColor: 'grey' }]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
value={item}
onChangeText={(text)=>onChangeText(text,index)}
/>
))}
</View>
);
}
You can do something like that:
this.state = { values: [] };
const textInputs = [];
for(let i=0; i< this.state.noOfStores; i++) {
textInputs.push(
<TextInput
style ={[styles.input,{ backgroundColor: theme.colors.lightGray }]}
placeholder=" Name "
keyboardType={'default'}
placeholderTextColor="gray"
onChangeText={text => this.onChangeText(text,i)}
/>
)
this.setState({ values: [...this.state.values, ''] });
}
onChangeText = (text,index) => {
const values = [...this.state.values];
values[index] = text;
this.setState({ values });
}
Then in render method:
<View>
{textInputs}
</View>
Here is my code there are 3 input fields, in uniqueIdNo whenever I have to type it should automatic convert to uppercase. I am using the toUpperCase() function, it converts to the upper case also, but
if I am writing ab two-letter its coming AAB means whatever the first letter I am typing it adding that and coming two times.
this.state={
firstName: props.firstName || '',
lastName: props.lastName || '',
uniqueIdNo:props.uniqueIdNo || '',
}
onChangeText = async (text, identifier) => {
if (identifier === "FN") {
this.setState({
firstName: text
});
} else if (identifier === "LN") {
this.setState({
lastName: text
});
} else if (identifier === "UIN") {
this.setState({
uniqueIdNo: text.toUpperCase()
});
}
};
<Item style={{ borderColor: "#00fff", borderBottomWidth: 0.6 }}>
<Input
value={firstName}
keyboardType="default"
onChangeText={text => this.onChangeText(text, "FN")}
/>
</Item>
<Item style={{ borderColor: "#00fff", borderBottomWidth: 0.6 }}>
<Input
value={lastName}
keyboardType="default"
onChangeText={text => this.onChangeText(text, "LN")}
/>
</Item>
<Item style={{ borderColor: "#00fff", borderBottomWidth: 0.6 }}>
<Input
value={uniqueIdNo}
onChangeText={text => this.onChangeText(text, "UIN")}
/>
</Item>
You can use the keyboardType property for that in android you can set keyboard type to visible-password and iOS default.
keyboardType={Platform.OS === 'ios' ? 'default' : 'visible-password'}
Hey you can check my expo-snack link, i couldnt find the error, please do check : expo-snack
Code is as below :
import * as React from 'react';
import { Text, View, StyleSheet,TextInput } from 'react-native';
export default class App extends React.Component {
constructor(props){
super(props)
this.state={
firstName:'',
lastName: '',
uniqueIdNo: '',
}
}
onChangeText = async (text, identifier) => {
if (identifier === "FN") {
this.setState({
firstName: text
});
} else if (identifier === "LN") {
this.setState({
lastName: text
});
} else if (identifier === "UIN") {
this.setState({
uniqueIdNo: text.toUpperCase()
});
}
};
render() {
let {firstName,lastName,uniqueIdNo} = this.state;
return (
<View style={styles.container}>
<View style={{ borderColor: "#00fff", borderBottomWidth: 0.6 }}>
<TextInput
value={firstName}
keyboardType="default"
onChangeText={text => this.onChangeText(text, "FN")}
/>
</View>
<View style={{ borderColor: "#00fff", borderBottomWidth: 0.6 }}>
<TextInput
value={lastName}
keyboardType="default"
onChangeText={text => this.onChangeText(text, "LN")}
/>
</View>
<View style={{ borderColor: "#00fff", borderBottomWidth: 0.6 }}>
<TextInput
value={uniqueIdNo}
onChangeText={text => this.onChangeText(text, "UIN")}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
Hope it helps. feel free for doubts
Try this:
if (identifier === "UIN") {
var uppercasetext = text.toUpperCase();//To convert Upper Case
this.setState({
uniqueIdNo: uppercasetext
});
There is a property to input called autoCapitalize that can be used for uppercase-issues.
<Input
autoCapitalize="sentences"
/>
https://reactnative.dev/docs/textinput#autocapitalize
I am having an issue with React Native's this.setState() within a TextInput's onChangeText. I am trying to display the content of the TextInput in the Text tag below it. However, it displays nothing -- the setState() call never changes this.state.searchtext. I also get no errors. Thank you in advance for your help! Here is my code:
export default class ShowScreen extends Component {
constructor(props) {
super(props);
this.state = {
searchtext: ""
};
}
render() {
var thisscreen = (
<View>
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
pagingEnabled={true}
>
<View
style={{
flex: 1,
height: totalheight,
justifyContent: "space-around",
alignItems: "center",
width: totalwidth,
backgroundColor: "#FF0000"
}}
>
<TextInput
style={{ height: 80, fontSize: 20 }}
placeholder="placeholder"
value={this.state.searchtext}
onChangeText={searchtext =>
this.setState({ searchtext })
}
ref={input => {
this.textInput = input;
}}
returnKeyType="go"
/>
<Text>{this.state.searchtext}</Text>
</View>
</ScrollView>
</View>
);
return thisscreen;
}
}
In your TextInput add value prop
<TextInput
style={{height: 80, fontSize: 20}}
placeholder="placeholder"
value={this.state.searchtext}
onChangeText={(searchtext) => this.setState({ searchtext })}
ref={input => { this.textInput = input }}
returnKeyType="go"
/>
Hey you have used a variable to store screen code which is thisscreen. This might be preventing it from updating state.
Your render function should be like this:
render () {
return (
<View>
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
pagingEnabled={true}
>
<View style={{
flex: 1,
height: totalheight,
justifyContent: "space-around",
alignItems: "center",
width: totalwidth,
backgroundColor: "#FF0000"
}}>
<TextInput
style={{height: 80, fontSize: 20}}
placeholder="placeholder"
value={this.state.searchtext}
onChangeText={(searchtext) =>
this.setState({searchtext})}
ref={input => { this.textInput = input }}
returnKeyType="go"
/>
<Text>{this.state.searchtext}</Text>
</View>
</ScrollView>
</View>);
}
onChangeText={(search_text) => this.setState({searchtext:search_text})}
try this, that might do job.
When you use setState, we provide a JSON as parameter. Please follow below code.
<TextInput
style={{height: 80, fontSize: 20}}
placeholder="placeholder"
value={this.state.searchtext}
onChangeText={(searchtext) => this.setState({ searchtext: searchtext })} // <--
ref={input => { this.textInput = input }}
returnKeyType="go"
/>
Do let me know if it does not work.
I think there might bug in React onChangeText method. You just need to replace onChangetText to onChange then It will work fine.
<TextInput
style={{height: 80, fontSize: 20}}
placeholder="placeholder"
onChange={(text) => this.setState({searchtext : text})}
ref={input => { this.textInput = input }}
returnKeyType="go"
/>
For both iOS and Android simulators
The text just disappears/flickers when I start typing. I tried having an initial state of texts with some value instead of keeping it empty. With this the TextInput sticks to this initial state and does not update itself with new text entered.
I think the state is not updating with 'onChangeText' property, but I am not completely sure.
People have seem to solve this, as they had few typos or missing pieces in code. However I have checked mine thoroughly.
Please help if I have missed anything in the below code.
LoginForm.js
import React, { Component } from 'react';
import { Card, Button, CardSection, Input } from './common';
class LoginForm extends Component {
state = { email: '', password: '' }
render() {
return (
<Card>
<CardSection>
<Input
label="Email"
placeHolder="user#gmail.com"
onChangeText={text => this.setState({ email: text })}
value={this.state.email}
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
label="Password"
placeHolder="password"
onChangeText={text => this.setState({ password: text })}
value={this.state.password}
/>
</CardSection>
<CardSection>
<Button>
Log In
</Button>
</CardSection>
</Card>
);
}
}
export default LoginForm;
Input.js
import React from 'react';
import { TextInput, View, Text } from 'react-native';
const Input = ({ label, value, onChangeText, placeholder, secureTextEntry }) => {
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={containerStyle}>
<Text style={labelStyle}>{label}</Text>
<TextInput
secureTextEntry={secureTextEntry}
placeholder={placeholder}
autoCorrect={false}
style={inputStyle}
value={value}
onChangeText={onChangeText}
/>
</View>
);
};
const styles = {
inputStyle: {
color: '#000',
paddingRight: 5,
paddingLeft: 5,
fontSize: 18,
lineHeight: 23,
flex: 2
},
labelStyle: {
fontSize: 18,
paddingLeft: 20,
flex: 1
},
containerStyle: {
height: 40,
flex: 1,
flexDirection: 'row',
alignItems: 'center'
}
};
export { Input };
The only way to solve this was to change the way the values of TextInput fields are updated, with this code below.
value={this.state.email.value}
value={this.state.password.value}
You problem is how the Input component is written.
There is a render function written inside the stateless component which is not a React class component:
const Input = ({ label, value, onChangeText, placeHolder, secureTextEntry }) => ( // ← remove the wrapping parentheses
{
render() { // <--- this should not be here
↑
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={containerStyle} >
<Text style={labelStyle}>{label}</Text>
<TextInput
secureTextEntry={secureTextEntry}
autoCorrect={false}
placeholder={placeHolder}
style={inputStyle}
onChangeText={onChangeText}
value={value}
underlineColorAndroid="transparent"
/>
</View>
);
}
}
);
Change it to this:
const Input = ({ label, value, onChangeText, placeHolder, secureTextEntry }) => {
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={containerStyle} >
<Text style={labelStyle}>{label}</Text>
<TextInput
secureTextEntry={secureTextEntry}
autoCorrect={false}
placeholder={placeHolder}
style={inputStyle}
onChangeText={onChangeText}
value={value}
underlineColorAndroid="transparent"
/>
</View>
);
};
See running example
I want to submit value from text input, but when I console.log, the text that inputed before is undefined. I've already follow the instruction from react native get TextInput value, but still undefined.
this is state that I've made before:
this.state = {
comment_value: '',
comments: props.comments
}
submit = (args) => {
this.props.submit(args.comment_value)
}
this is the the function for submitted text:
addComment () {
var comment_value = this.state.comment_value
console.log('success!', comment_value)
})
this.props.submit('410c8d94985511e7b308b870f44877c8', '', 'e18e4e557de511e7b664b870f44877c8')
}
and this is my textinput code:
<TextInput
underlineColorAndroid='transparent'
placeholder='Enter your comment here'
multiline numberOfLines={4}
onChangeText={(text) => this.setState({comment_value: text})}
value={this.state.comment_value}
style={styles.textinput}
/>
</View>
<TouchableOpacity onPress={this.addComment.bind(this)}>
<View style={{flex: 1, flexDirection: 'column', backgroundColor: Colors.background, width: 70}}>
<Icon name='direction' type='entypo' color='#000'size={30} style={styles.icon} />
</View>
</TouchableOpacity>
This should definately be working try cleaning up your code like this
contructor(props) {
super(props);
this.state = {
comment_value: '',
}
}
addComment () {
console.log(this.state.comment_value); // should be defined
this.props.submit(this.state.comment_value);
}
render() {
return (
<View>
<TextInput
underlineColorAndroid='transparent'
placeholder='Enter your comment here'
multiline numberOfLines={4}
value={this.state.comment_value}
onChangeText={(text) => this.setState({comment_value: text})}
style={styles.textinput}
/>
<TouchableOpacity onPress={this.addComment.bind(this)}>
<View style={{flex: 1, flexDirection: 'column', backgroundColor: Colors.background, width: 70}}>
<Icon name='direction' type='entypo' color='#000'size={30} style={styles.icon} />
</View>
</TouchableOpacity>
</View>
);
}
EDIT: Based on your complete code sample it seems like you're incorrectly trying to update state by doing multiple this.state = ... which is incorrect, to update state you have to use this.setState({ ... })