ReactNative TextInput not letting me type - javascript

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

Related

Unable to display Formik Form

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>
);
}
}

Can't load components with props

Im making a component and calling it in my app.js with props inside like { placeholder }, but it always returns a refrenceError: Can't find variable placeholder. I don't understand why.
Calling it:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import * as firebase from 'firebase';
import { Input } from './components/input'
import { Button } from './components/button'
export default class App extends React.Component {
state = {
email: '',
password: '',
}
render() {
return (
<View style={styles.container}>
<Input
placeholder='Enter your email'
label='Email'
onChangeText={password => this.setState({ password })}
value={this.state.password}
/>
<Input
placeholder='Enter your password'
label='Password'
secureTextEntry
onChangeText={email => this.setState({ email })}
value={this.state.email}
/>
<Button>Login</Button>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
});
And the component
import React from 'react';
import { View, StyleSheet, Text, TextInput } from 'react-native';
const Input = () => {
return (
<View>
<Text style={styles.label}>Label</Text>
<TextInput
style={styles.input}
placeholder={ placeholder }
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
marginTop: 10,
width: '100%',
borderColor: '#eee',
borderBottomWidth: 2,
},
label: {
padding: 5,
paddingBottom: 0,
color: '#eee',
fontSize: 17,
fontWeight: '700',
width: '100%'
},
input: {
paddingRight: 5,
paddingLeft: 5,
paddingBottom: 2,
backgroundColor: '#eee',
fontSize: 18,
fontWeight: '700',
width: '100%',
}
})
export { Input };
const Input = ({ placeholder }) => { //<==== here
return (
<View>
<Text style={styles.label}>Label</Text>
<TextInput
style={styles.input}
placeholder={ placeholder }
/>
</View>
);
}
props will not be passing in automatically. It will be passed in as an argument, and your input component doesnt accept any argument and you're trying to access a variable placeholder and hence getting the error stated
Your Input is taking no props at all. You need to pass the props as parameters of the component function:
const Input = (props) => {
return (
<View>
<Text style={styles.label}>Label</Text>
<TextInput
style={styles.input}
placeholder={ props.placeholder }
/>
</View>
);
}
Accept props as a parameter in the Input component, then use props to access placeholder. You need to change the code of Input component to
const Input = (props) => {
return (
<View>
<Text style={styles.label}>Label</Text>
<TextInput
style={styles.input}
placeholder={ props.placeholder }
/>
</View>
);
}
Hope this will help!

Undefined TextInput Value

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({ ... })

Inserting data from array of objects to array React Native

I am trying to get user input, create an array of objects from userInput and save that array of objects into an array. Below is code I have written, but no output.
import React, { Component } from 'react';
import {Text, View, StyleSheet, TextInput, Image, TouchableOpacity, ListView} from 'react-native';
//import {Actions} from 'react-native-router-flux';
const count = 0;
export default class SecondPage extends Component {
constructor(props) {
super(props);
this.state = {
quan:'',
desc:'',
amt:'',
dataStorage :[],
data: { quantity: this.quan, description: this.desc, amount: this.amt },
}
}
_add(){
console.log('Add button pressed');
this.state.dataStorage[count].push(this.state.data);
console.log(this.state.data);
count++;
}
render(){
return(
<View style={styles.container}>
<View style={styles.itemDescription}>
<Text style={styles.itemDescriptionText}>QUANTITY</Text>
<Text style={styles.itemDescriptionText}>DESCRIPTION</Text>
<Text style={styles.itemDescriptionText}>AMOUNT</Text>
<TouchableOpacity style={styles.addButton} onPress={this._add}>
<Text style={styles.addButtonText}>ADD</Text>
</TouchableOpacity>
</View>
<View style={styles.rowsOfInput}>
<TextInput style = {styles.nameInput}
onChangeText={(text) => this.setState({quan: text})}
value = {this.state.quan}
autoCapitalize='none'
autoCorrect={false}
returnKeyType="next"
keyboardAppearance="dark"
/>
<TextInput style = {styles.nameInput}
onChangeText={(text) => this.setState({desc: text})}
value = {this.state.desc}
autoCapitalize='none'
autoCorrect={false}
returnKeyType="next"
keyboardAppearance="dark"
/>
<TextInput style = {styles.nameInput}
onChangeText= {(text) => this.setState({amt: text})}
value = {this.state.amt}
autoCapitalize='none'
autoCorrect={false}
returnKeyType="next"
keyboardAppearance="dark"
/>
</View>
</View>
)}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
},
itemDescription: {
marginTop:20,
backgroundColor:'#00CED1',
flexDirection:'row',
justifyContent:'space-between',
},
itemDescriptionText:{
fontSize:12,
color:'white',
},
addButton:{
borderWidth:1,
height:20,
borderRadius:5,
overflow:'hidden',
backgroundColor:'red',
},
addButtonText:{
paddingLeft:10,
paddingRight:10,
},
nameInput:{
flex:1,
height: 20,
textAlignVertical:'bottom',
paddingLeft: 5,
paddingRight: 5,
fontSize: 12,
backgroundColor:'#E0FFFF',
},
hairLine:{
height:1,
backgroundColor:'black',
marginTop:0,
marginLeft:20,
marginRight:20
},
rowsOfInput:{
// flex:1,
flexDirection:'row',
justifyContent:'space-around'
},
});
Whats wrong in the code? I want to store userInput for each entry into QUANTITY, DESCRIPTION, AMOUNT as array of object.
One of your issues is a scoping issue. Change your _add method to this.
_add = () => {
let dataStorage = [{amt: this.state.amt, quan: this.state.quan, desc: this.state.desc}, ...this.state.dataStorage]
console.log(dataStorage)
this.setState({dataStorage})
}
Also, your data property on state will never work and is unnecessary.
Here is an example.
It still won't display anything because you do nothing with dataStorage.

Passing checkbox value to show / hide Password via react native

I'm using Firebase auth I will want to add a Check box, it will display the password in the password text box and hide it when it is clicked again
How to Passing checkbox value to show / hide Password?
This is my Login Page Code:
export default class Login extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
response: ''
}
this.signUp = this.signUp.bind(this)
this.login = this.login.bind(this)
}
async signUp() {
try {
await firebase.auth().createUserWithEmailAndPassword(this.state.email, this.state.password)
this.setState({
response: 'Account Created!'
})
setTimeout(() => {
this.props.navigator.push({
id: 'App'
})
}, 500)
} catch (error) {
this.setState({
response: error.toString()
})
}
}
async login() {
try {
await firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password)
this.setState({
response: 'user login in'
})
setTimeout(() => {
this.props.navigator.push({
id: 'App'
})
})
} catch (error) {
this.setState({
response: error.toString()
})
}
}
render() {
return (
<View style={styles.container}>
<View style={styles.containerInputes}>
<TextInput
placeholderTextColor="gray"
placeholder="Email"
style={styles.inputText}
onChangeText={(email) => this.setState({ email })}
/>
<TextInput
placeholderTextColor="gray"
placeholder="Password"
style={styles.inputText}
password={true}
secureTextEntry={true}
onChangeText={(password) => this.setState({ password })}
/>
</View>
<TouchableHighlight
onPress={this.login}
style={[styles.loginButton, styles.button]}
>
<Text
style={styles.textButton}
>Login</Text>
</TouchableHighlight>
<TouchableHighlight
onPress={this.signUp}
style={[styles.loginButton, styles.button]}
>
<Text
style={styles.textButton}
>Signup</Text>
</TouchableHighlight>
</View>
)
}
}
import React, {useState} from 'react';
import {TextInput} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome5';
const [hidePass, setHidePass] = useState(true);
<TextInput
placeholder="Password"
secureTextEntry={hidePass ? true : false}>
<Icon
name={hidePass ? 'eye-slash' : 'eye'}
onPress={() => setHidePass(!hidePass)} />
<TextInput/>
One way of doing that is to set a state variable like showPassword and toggle it whenever the checkbox is checked. Like so:
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
TextInput,
Switch
} from 'react-native';
export default class DemoProject extends Component {
constructor(props) {
super(props);
this.toggleSwitch = this.toggleSwitch.bind(this);
this.state = {
showPassword: true,
}
}
toggleSwitch() {
this.setState({ showPassword: !this.state.showPassword });
}
render() {
return (
<View>
<TextInput
placeholderTextColor="gray"
placeholder="Password"
secureTextEntry={this.state.showPassword}
onChangeText={(password) => this.setState({ password })}
/>
<Switch
onValueChange={this.toggleSwitch}
value={!this.state.showPassword}
/>
<Text>Show</Text>
</View>
)
}
}
AppRegistry.registerComponent('DemoProject', () => DemoProject);
NOTE: This won't work if you set the password prop!!!
So just use a regular TextInput and utilize the secureTextEntry prop.
here is my way of doing it
const LoginScreen = props => {
const [icon, setIcon] = useState("eye-off")
const [hidePassword, setHidePassword] = useState(true)
_changeIcon = () => {
icon !== "eye-off"
? (setIcon("eye-off"), setHidePassword(false))
: (setIcon("eye"), setHidePassword(true))
}
i used native base for textInput
<Input
secureTextEntry={hidePassword}
placeholder="Password"
placeholderTextColor={palette.gray}
/>
<Icon name={icon} size={20} onPress={() => _changeIcon()} />
this will change the secureTextEntry on click
Please correct me if I am wrong, are you asking how to create a check box? If so, you have two routes, either use a 3rd party library from one of the many check boxes on the web or you can create one yourself.
Steps:
download a icon library as such https://github.com/oblador/react-native-vector-icons so you can use the two material design icons from enter link description here eg. checkbox-blank-outline and checkbox-marked to emulate clicked and not clicked
using those two new icons, simply create a new component with what ever functionality you desire and handle all states and such the way you want.
Basic implementation:
Have a state that controls if it was checked or not
Have a onPress function to handle both states and trigger the respective props
// the on press function
onPress = () => {
if (this.sate.checked) {
this.props.checked();
} else {
this.props.unChecked();
}
}
// the rendered component
<Icon name={this.state.checked ? "checkbox-marked" : "checkbox-blank-outline" onPress={this.onPress}/>
this is how i did in simple way,
my checkbox and password component,
<input style={ inputUname } type={this.state.type} placeholder="Password" value={ this.state.password } onChange={this.handlePassword}/>
<Checkbox defaultChecked={false} onSelection={this.showPassword} value="false" name="Checkbox" label="Show password"/>
my state,
this.state = {
type: 'input'
}
here is my show password event,
showPassword(e){
this.setState( { showpassword: !this.state.showpassword }) // this is to change checkbox state
this.setState( { type: this.state.type === 'password' ? 'text' : 'password' }) // this is to change input box type text/password change
}
enter image description here
const [password, setPassword] = useState("")
const [passwordVisible, setPasswordVisible] = useState(true)
<TextInput
mode='outlined'
style={{ flex: 1, marginHorizontal: 20, marginTop: 30 }}
autoCapitalize="none"
returnKeyType="next"
label=' Password '
keyboardType="default"
underlineColorAndroid={'rgba(0,0,0,0)'}
right={<TextInput.Icon color={colors.white} name={passwordVisible ? "eye" : "eye-off"} onPress={onPressEyeButton} />}
text='white'
maxLength={50}
onChangeText={(text) => { setPassword(text) }}
value={password}
defaultValue={password}
theme={styles.textInputOutlineStyle}
secureTextEntry={passwordVisible}
/>
textInputOutlineStyle: {
colors: {
placeholder: colors.white,
text: colors.white,
primary: colors.white,
underlineColor: 'transparent',
background: '#0f1a2b'
}
},
[1]: https://i.stack.imgur.com/C7ist.png
Step1: Create a useState hook to store the initial values of password and secureTextEntry:
const [data, setData] = useState({
password: '',
isSecureTextEntry: true,
});
Step2: Update the state according to the conditions:
<View>
<TextInput
style={styles.textInput}
placeholder="Enter Password"
secureTextEntry={data.isSecureTextEntry ? true : false}
onChangeText={data => {
setData({
password: data,
//OR
/*
//Array destructuring operator to get the existing state i.e
...data
*/
//and then assign the changes
isSecureTextEntry: !data.isSecureTextEntry,
});
}}></TextInput>
<TouchableOpacity
onPress={() => {
setData({
//...data,
isSecureTextEntry: !data.isSecureTextEntry,
});
}}>
<FontAwesome
name={data.isSecureTextEntry ? 'eye-slash' : 'eye'}
color="gray"
size={25}
paddingHorizontal="12%"
/>
</TouchableOpacity>
</View>
<View>
<Input
style={styles.input}
onChangeText={onChangeData}
multiline={false}
secureTextEntry={!showPassword}
textContentType={"password"}
value={data.password}
placeholder="Password"
/>
<TouchableHighlight
style={{
textAlign: "right",
position: "absolute",
right: 20,
bottom: 22,
zIndex: 99999999,
}}
onPress={() => setShowPassword(!showPassword)}
>
<>
{showPassword && (
<Ionicons name="eye-outline" size={22} color="#898A8D" />
)}
{!showPassword && (
<Ionicons name="eye-off-outline" size={22} color="#898A8D" />
)}
</>
</TouchableHighlight>
</View>;

Categories

Resources