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>;
Related
interface FormValues {
friendEmail: string;
}
const initialValues: FormValues = {
friendEmail: '',
};
export const Page: React.FunctionComponent<PageProps> = ({
toggleShowPage,
showPage,
}) => {
const [errorMessage, setErrorMessage] = useState('');
const validationSchema = emailValidationSchema;
useEffect(() => {
if (showPage) return;
initialValues.friendEmail = '';
}, [showPage]);
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
called: isMutationCalled,
},
] = useCreateUserRelationMutation({
onCompleted: (data: any) => {
showAlert();
},
});
const addFriend = React.useCallback(
(id: Number) => {
console.log('Whats the Id', id);
createUserRelationMutation({
variables: {
input: { relatedUserId: id, type: RelationType.Friend, userId: 7 },
},
});
},
[createUserRelationMutation],
);
const getFriendId = React.useCallback(
(data: any) => {
//console.log('Email', initialValues.friendEmail);
if (data) {
if (data.users.nodes.length == 0) {
console.log('No user');
setErrorMessage('User Not Found');
Alert.alert('User Not Found');
} else {
console.log('ID', data.users.nodes[0].id);
addFriend(Number(data.users.nodes[0].id));
}
}
},
[addFriend],
//[friendEmail, addFriend],
);
const [loadUsers] = useUsersLazyQuery({
onCompleted: getFriendId,
onError: _onLoadUserError,
});
const handleSubmitForm = React.useCallback(
(values: FormValues, helpers: FormikHelpers<FormValues>) => {
console.log('Submitted');
loadUsers({
variables: {
where: { email: values.friendEmail },
},
});
//setFriendEmail('');
values.friendEmail = '';
},
[loadUsers],
//[loadUsers, friendEmail]
);
if (!addingFriendLoading && isMutationCalled) {
if (addingFriendData) {
console.log('Checking');
}
if (addingFriendError) {
console.log('errorFriend', addingFriendError.message);
}
}
return (
<Modal
visible={showAddFriendEmailPage}
animationType="slide"
transparent={true}>
<SafeAreaView>
<View style={scaledAddFriendEmailStyles.container}>
<View style={scaledAddFriendEmailStyles.searchTopContainer}>
<View style={scaledAddFriendEmailStyles.searchTopTextContainer}>
<Text
style={scaledAddFriendEmailStyles.searchCancelDoneText}
onPress={toggleShowPage}>
Cancel
</Text>
<Text style={scaledAddFriendEmailStyles.searchTopMiddleText}>
Add Friend by Email
</Text>
<Text style={scaledAddFriendEmailStyles.searchCancelDoneText}>
Done
</Text>
</View>
<View style={scaledAddFriendEmailStyles.searchFieldContainer}>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
}) => (
<View>
<View>
<Item style={scaledAddFriendEmailStyles.searchField}>
<TextInput
style={scaledAddFriendEmailStyles.searchText}
placeholder="Email"
onChangeText={handleChange('friendEmail')}
//onChangeText={e => console.log('Workinggg')}
onBlur={handleBlur('friendEmail')}
value={values.friendEmail}
autoCapitalize="none"
/>
{/* <Field
component={Input}
name='friendEmail'
placeholder="Email"
//handleChange={handleChange}
handleBlur={handleBlur}
//onChange={handleChange}
//onChangeText={handleChange('friendEmail')}
//onBlur={handleBlur('friendEmail')}
value={values.friendEmail}
autoCapitalize="none"
/> */}
</Item>
</View>
<View>
<Button
onPress={handleSubmit}>
<Text>
Add Friend{' '}
</Text>
</Button>
</View>
</View>
)}
</Formik>
</View>
</View>
</View>
</SafeAreaView>
</Modal>
);
};
Why am I unable to write anything inside my Input field? I have tried using onChangeand handleChangeboth but it doesn't make a difference. Other SO answers suggested that I should remove value but examples of Formik usage that I see online suggest otherwise.
I am trying to follow this for my Formik validation:
https://heartbeat.fritz.ai/build-and-validate-forms-in-react-native-using-formik-and-yup-6489e2dff6a2
EDIT:
I also tried with setFieldValuebut I still cannot type anything.
const initialValues: FormValues = {
friendEmail: '',
};
export const AddFriendEmailPage: React.FunctionComponent<AddFriendEmailPageProps> = ({
toggleShowPage,
showAddFriendEmailPage,
}) => {
const [errorMessage, setErrorMessage] = useState('');
const validationSchema = emailValidationSchema;
useEffect(() => {
if (showAddFriendEmailPage) return;
initialValues.friendEmail = '';
}, [showAddFriendEmailPage]);
const _onLoadUserError = React.useCallback((error: ApolloError) => {
setErrorMessage(error.message);
Alert.alert('Unable to Add Friend');
}, []);
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
called: isMutationCalled,
},
] = useCreateUserRelationMutation({
onCompleted: (data: any) => {
showAlert();
},
});
const addFriend = React.useCallback(
(id: Number) => {
console.log('Whats the Id', id);
createUserRelationMutation({
variables: {
input: { relatedUserId: id, type: RelationType.Friend, userId: 7 },
},
});
},
[createUserRelationMutation],
);
const getFriendId = React.useCallback(
(data: any) => {
//console.log('Email', initialValues.friendEmail);
if (data) {
if (data.users.nodes.length == 0) {
console.log('No user');
} else {
console.log('ID', data.users.nodes[0].id);
addFriend(Number(data.users.nodes[0].id));
}
}
},
[addFriend],
//[friendEmail, addFriend],
);
const [loadUsers] = useUsersLazyQuery({
onCompleted: getFriendId,
onError: _onLoadUserError,
});
const handleSubmitForm = React.useCallback(
(values: FormValues, helpers: FormikHelpers<FormValues>) => {
console.log('Submitted');
loadUsers({
variables: {
where: { email: values.friendEmail },
},
});
//setFriendEmail('');
values.friendEmail = '';
},
[loadUsers],
//[loadUsers, friendEmail]
);
return (
<Modal
visible={showPage}
animationType="slide"
transparent={true}>
<SafeAreaView>
<View style={scaledAddFriendEmailStyles.container}>
<View style={scaledAddFriendEmailStyles.searchFieldContainer}>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({
handleChange,
setFieldValue,
handleBlur,
handleSubmit,
isSubmitting,
values,
}) => {
const setEmail = (friendEmail: string) => {
setFieldValue('friendEmail', friendEmail)
}
return(
<View>
<View>
<Item>
<TextInput
placeholder="Email"
onChangeText={setEmail}
onBlur={handleBlur('friendEmail')}
value={values.friendEmail}
autoCapitalize="none"
/>
</Item>
</View>
<View >
<Button
onPress={handleSubmit}>
<Text >
Add Friend{' '}
</Text>
</Button>
</View>
</View>
)}}
</Formik>
</View>
</View>
</View>
</SafeAreaView>
</Modal>
);
};
Formik's Field component doesn't support React native yet. Check this github issue for more details
However you can make use of TextInput in place of field and use it with onChangeText handler
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
}) => (
<View>
<View>
<Item style={scaledAddFriendEmailStyles.searchField}>
<TextInput
placeholder="Email"
onChangeText={handleChange('friendEmail')}
onBlur={handleBlur('friendEmail')}
value={values.friendEmail}
/>
</Item>
</View>
<View >
<Button
onPress={handleSubmit}
>
<Text >
Add Friend{' '}
</Text>
</Button>
</View>
</View>
)}
</Formik>
you can read more about Formik's usage with react-native in its documentation here
try this:
<Input
placeholder="Email"
onChange={e => setFieldValue('friendEmail', e.currentTarget.value)}
onBlur={handleBlur}
value={values.friendEmail}
autoCapitalize="none"
/>
I think there are a couple of issues in your codebase.
onChangeText={handleChange('friendEmail')}. It will trigger the handleChange while rendering the component not when you are actualy typing in the input box.
handleChange function of Formik takes React.ChangeEvent instead of value. Check here . While onChangeText of react-native provides changed text of the input not event. Check here
You can use setFieldValue function for this case:
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
values,
setFieldValue
}) => {
const setEmail = (email) => {
setFieldValue('friendEmail', email)
}
return (
<View>
<View>
<Item style={scaledAddFriendEmailStyles.searchField}>
<TextInput
placeholder="Email"
onChangeText={setEmail}
value={values.friendEmail}
/>
</Item>
</View>
</View>
)
}}
</Formik>
Please Note: I've never used formik with react-native. Just trying to connect the dots.
Formik now works fine with React Native, but another thing to be aware of is that the name in your form control must match the name of the property in the schema used by Formik.
For example, if using the following Yup schema:
const schema = yup.object({
personName: yup.string().required('Name required')
});
Then the following won't work because the Yup schema (personName) and the form control (nameofPerson) don't match; the user won't be able to type into the field:
<Form.Control
name="nameOfPerson"
value={values.personName}
onChange={handleChange}
onBlur={handleBlur}
type="text"
isValid={!errors.personName && !!touched.personName}
isInvalid={!!errors.personName && !!touched.personName}
/>
To make it work, the name should be the same as the Yup property; in this case, personName:
<Form.Control
name="personName"
value={values.personName}
onChange={handleChange}
onBlur={handleBlur}
type="text"
isValid={!errors.personName && !!touched.personName}
isInvalid={!!errors.personName && !!touched.personName}
/>
This example is using React-Bootstrap Form.Control but should apply to any manner of creating form controls.
the problem is that I am trying enable/disable fields in a form with the use of a
I have tried following the steps in this tutorial
https://dev.to/skptricks/react-native-enable-and-disable-textinput-programmatically-1b99
Here is where I have got to so far
onPressButton = () => {
this.setState({ TextInputDisableStatus: false })
}
<TextInput
label="Name"
placeholder="Colin Molony"
autoCapitalize="none"
keyboardType="default"
keyboardAppearance="default"
returnKeyType="next"
returnKeyLabel="Next"
blurOnSubmit={false}
selectTextOnFocus={true}
style={styles.textInput}
editable={this.state.TextInputDisableHolder}
/>
ProfileScreen.navigationOptions = {
title: 'Profile Page',
headerRight: (
<Ionicons
style={{padding: 15}}
name={Platform.OS === 'ios' ? 'ios-create' : 'md-create'}
size={26}
onPress={this.onPressButton}
/>
),
};
When I click the icon I get the following error this.setstate is not a function
I think there is a naming problem. I followed your link and the author there initializes the following state:
constructor() {
super();
this.state = { TextInputDisableStatus: true }
}
In the onPress method, you are updating the status with:
onPressButton = () => {
this.setState({ TextInputDisableStatus: false })
}
But then inside the TextInput the author and you are referring to
editable={this.state.TextInputDisableHolder}
this should probably be changed to:
editable={this.state.TextInputDisableStatus}
In addition you have to change:
onPressButton() {
this.setState({ TextInputDisableStatus: false })
}
and:
<Ionicons
style={{padding: 15}}
name={Platform.OS === 'ios' ? 'ios-create' : 'md-create'}
size={26}
onPress={() => this.onPressButton()}
/>
I have some issues with TextInput when getting the data from API when calling the function I'm declaring it to fetch the API and get the data Depending on the input
I have a warning like
can't find variable searchInput
and I'm defining the search input in the state and put them to the value of the input, I think the code is right or what?
Code
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
TextInput,
LinearGradient,
ActivityIndicator,
TouchableOpacity
} from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
export default class Search extends Component {
constructor() {
super();
this.ApiKey = "****";
this.state = {
searchInput: "",
searchResult: null,
error: "",
isLoading: false
};
}
searchCity = async () => {
this.setState({
isLoading: true
});
const url = `http://api.openweathermap.org/data/2.5/weather?q=${searchInput}&units=metric&appid=${
this.ApiKey
}`;
await fetch(url)
.then(res => res.json())
.then(responseJson =>
this.setState({
isLoading: false,
searchResult: {
name: responseJson.name,
country: responseJson.sys.country,
main: responseJson.weather[0].main,
description: responseJson.weather[0].description,
temp: responseJson.main.temp
}
})
)
.catch(error => this.setState({ error }));
};
render() {
const { searchInput, searchResult, isLoading, error } = this.state;
if (!isLoading) {
return (
<View
style={{
backgroundColor: "#2b3654",
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
>
{isLoading && <Text style={styles.Text}> Loading...</Text>}
<ActivityIndicator size="large" color="00ff00" />
</View>
);
} else if (error) {
return (
<View>
<Text>{error}</Text>
</View>
);
}
if (searchResult) {
return (
<LinearGradient colors={["rgba(0,0,0,0.05)", "rgba(0,0,0,0)"]}>
<View>
<Text>{searchResult.name}</Text>
<Text> {searchResult.main}</Text>
<Text> {searchResult.description}</Text>
<Text> {searchResult.temp}</Text>
</View>
</LinearGradient>
);
} else {
return (
<View style={styles.container}>
<View style={styles.searchSection}>
<TouchableOpacity onPress={this.searchCity}>
<Icon
style={styles.searchIcon}
name="ios-search"
size={15}
color="#fff"
/>
</TouchableOpacity>
<TextInput
style={styles.input}
placeholder="Find Your City.."
placeholderTextColor="#fff"
underlineColorAndroid="transparent"
autoCapitalize="none"
onChangeText={searchInput => {
this.setState({ searchInput });
}}
onSubmitEditing={this.searchCity}
value={searchInput}
/>
</View>
</View>
);
}
}
}
You need to use this.state.searchInput
The line should be:
const url = `http://api.openweathermap.org/data/2.5/weather?q=${this.state.searchInput}...`;
The problem is in your URL, you have used searchInput there...
use this.state.searchInput
or you can use destructuring
const { searchInput } = this.state;
const url = `http://api.openweathermap.org/data/2.5/weather?q=${searchInput}&units=metric&appid=${
this.ApiKey
}`;
I have a class that I want the text input inside it to focus on the parent being selected.
class ListItem extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
editable: this.props.item.editable,
value: this.props.item.value,
heading: this.props.item.heading,
item: this.props.item.item,
}
}
_onPress = () => {
this.setState({ editable: true});
this.props.onPressItem(this.props.index, this.props, this.state);
}
_onSearchTextChanged = (event) => {
this.setState({ value: event.nativeEvent.text });
};
_handleSaveEvent = (e) => {
this.setState({ editable: false });
alert('works');
//Add in saving item
}
render() {
var editable = this.state.editable;
var heading = this.state.heading;
var value = this.state.value;
return (
<TouchableHighlight onPress={this._onPress} underlayColor='#dddddd'>
<View>
<View style={styles.rowContainer}>
<View style={styles.textContainer}>
<Text style={styles.title}>{heading}: </Text>
{this.state.editable?
<TextInput
style={styles.searchInput}
value={value.toString()}
onChange={this._onSearchTextChanged}
keyboardType="default"
returnKeyType="done"
onSubmitEditing={this._handleSaveEvent}/>
:
<Text style={styles.price}>{value}</Text>
}
{}
</View>
</View>
<View style={styles.separator}/>
</View>
</TouchableHighlight>
);
}
}
Ive tried adding
autoFocus={true}
Ive also tried adding
ref={this.props.index}
But when I try to focus that it tells me its not defined (this.refs[this.props.index].focus();)
I would like it to be focused when the 'editable' state is enabled, I am not sure why this seems so hard. My background is more in C#, Angular 2+ etc so maybe its just how react is structured is throwing me
on the onPress event of TouchableHighlight setState editable: true and set autoFocus={this.state.editable} in TextInput..it will work
<TextInput
style={styles.searchInput}
value={value.toString()}
onChange={this._onSearchTextChanged}
keyboardType="default"
autoFocus={this.state.editable}
returnKeyType="done"
onSubmitEditing={this._handleSaveEvent}
/>
You can try this. Provide ref as a function in <TextInput /> like this:
<TextInput
ref ={ref => this.inputText = ref}
style={styles.searchInput}
keyboardType="default"
placeholder="Type anything"
returnKeyType="done"/>
And now on <Button />onPress, focus the <TextInput /> like this:
<TouchableHighlight onPress={() => this.inputText.focus()}>
<Text>Click</Text>
</TouchableHightlight>
This should work. Let me know if there is any problem.
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