I am using formik in react native app using expo. Whilst using it on login form it is giving this error:
ReferenceError: Can't find variable: values
<Formik
initialValues={{ email: '', password: '' }}
onSubmit={ values => {this.handleSubmit(values)}}
>
{formikProps => (
<>
<FormInput
name="email"
value={values.email}
onChangeText={formikProps.handleChange('email')}
placeholder="Enter email"
autoCapitalize="none"
iconName="ios-mail"
iconColor="#2C384A"
/>
<FormInput
name="password"
value={values.password}
onChangeText={formikProps.handleChange('password')}
placeholder="Enter password"
secureTextEntry
iconName="ios-lock"
iconColor="#2C384A"
/>
<View style={styles.buttonContainer}>
<FormButton
buttonType="outline"
onPress={formikProps.handleSubmit}
title="LOGIN"
buttonColor="#039BE5"
/>
</View>
</>
)}
</Formik>
why it is not recognizing values as I was following the tutorial accurately?
Your problem is that you're not passing values, that's why you're getting that error.
change:
{formikProps => (
To:
{({formikProps, values}) => (
For more information, check the official documentation here.
Related
I am following the tutorial
In my App.js , i have this code
const nhost = new NhostClient({ subdomain: subdomain, region: region, });
I have wrapped my code with nhostprovider
<NhostProvider nhost={nhost}>
<View>
<Text>hellooooooooo</Text>
<Text>hello</Text>
<Text>hello</Text>
<Text>hello</Text>
<TextInput
label="Email"
value={text}
onChangeText={(text) => setText(text)}
/>
<TextInput
label="password"
value={password}
onChangeText={(text) => setPassword(text)}
/>
<Button icon="login" mode="Contained" onPress={() => register()}>
Press me
</Button>
</View>
</NhostProvider>
But on android emulator, i am getting error
ge.create is not a function ....ge.create is undefined
I have one more question. I am writing code in reat native, expo , android emulator. what should i put in client url and redirect url ?
https://prnt.sc/n45Ke9zY7v8c
I followed documentation. In youtube video, its something else and in documentation, its something else.
I have created a signup form in react native with formik and yup.According to the documentation I have added the react native picker.
<Formik
initialValues={{ password: '', first_name: '', email: '', passwordConfirmation: '' }}
onSubmit={values => handleSubmit(values)}
validationSchema={registerSchema}
>
{({ handleChange, handleBlur, handleSubmit, values, touched, errors }) => (
<View>
<TextInput
style={styles.textInputTop}
onChangeText={handleChange('first_name')}
onBlur={handleBlur('first_name')}
value={values.first_name}
label="First Name"
mode="outlined"
/>
<Text style={styles.errorMsg}>{touched.first_name && errors.first_name}</Text>
//Other Fields I have not mentioned in the code
<View style={styles.pickerContainer}>
<Text style={styles.depText}>Department</Text>
<Picker
style={{ height: 50, width: 150 }}
onValueChange={(itemValue, itemIndex) => setdepartment(itemValue)}
mode={"dropdown"}
>
<Picker.Item label="Management" value="Management" />
<Picker.Item label="HR" value="HR" />
<Picker.Item label="Accounting" value="Accounting" />
<Picker.Item label="Sales" value="Sales" />
</Picker>
</View>
<Button style={styles.btn} mode="contained" onPress={handleSubmit}>
<Text style={{ color: "white" }}>Sign Up</Text>
</Button>
</View>
)}
</Formik>
I need to add formik and yup to the picker to make it a required field. How do I do it?
If it is not possible with formik and yup, then how I can make the picker required.
on the registerSchema make:
department: Yup.string().required('this field is required')
department will hold the selected value from the picker, you may change the type from string to array depending on the selected value.
before installing Formik, my input looked like so:
const [search, setSearch] = useState('');
....
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
name="search"
type="search"
value={search}
onChangeText={(e) => setSearch(e)}
autoCorrect={false}
defaultValue={search}
/>
<Button
disabled={!search}
title="Create"
onPress={(e) => {
createNewCar(e);
}}
/>
</View>
in onChangeText, I would set every character I typed to a state prop called search. With every key that I typed, an API called would be made to get some data from the db.
for example:
if I typed h into the input, the db would return 2 cars honda, hyundai
I read that Formik can simplify a lot of the form setup in React, so I downloaded it, however, the handleChange prop from Formik wants to keep track of values.search
<Formik
initialValues={{
search,
}}
onSubmit={(values) => {
console.log('values', values);
}}>
{({ handleChange, handleSubmit, values }) => (
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
autoCorrect={false}
value={values.search}
onChangeText={(e) => {
handleChange(values.search);
setSearch(e);
}}
/>
<Button
disabled={!search}
title="Create"
onPress={handleSubmit}
/>
</View>
)}
</Formik>
Now I can't type into the form because value is pointing at values.search instead of search like it did originally.
Question
How do I fire setSearch in onChangeText but also add search into the formik values prop?
you can make use of setFieldValue('search', e.target.value) instead of handleChange() change the code to the following:
<Formik
initialValues={{
search,
}}
onSubmit={(values) => {
console.log('values', values);
}}>
{({ handleChange, handleSubmit, values, setFieldValue }) => (
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
autoCorrect={false}
value={values.search}
onChangeText={(e) => {
//handleChange(values.search);
setFieldValue('search', e.target.value)
setSearch(e);
}}
/>
<Button
disabled={!search}
title="Create"
onPress={handleSubmit}
/>
</View>
)}
</Formik>
I'm using native-base's form to handle user's username and password.
When I press next or go from keyboard, it doesn't move cursor to the next or doesn't submit the inputs. How can we fix this?
import { Form } from 'native-base';
<Form style={styles.formStyle}>
<AuthFieldInput
placeholder="Username or Email"
value={this.state.username}
onChangeText={username => this.setState({username})}
returnKeyType="next"/>
<AuthFieldInput
placeholder="Password"
value={this.state.password}
onChangeText={password => this.setState({password})}
secureTextEntry
returnKeyType="go"/>
</Form>
Here is <AuthField> render function
import { Item, Label, Input, Text } from 'native-base';
<Item>
<Input
value={value}
onChangeText={onChangeText}
placeholder={placeholder}
autoCorrect={false}
secureTextEntry={secureTextEntry}
returnKeyType={returnKeyType}
/>
</Item>
Thank you!
I was getting error as "_this2.refs.password.focus" is not a function on onSubmitEditing of TextInput.
This is how I fixed it:
Upgraded package for native-base "^2.4.2” to native-base "^2.7.1”.
Sharing my sample code below:
<Item floatingLabel>
<Label>Mobile Number</Label>
<Input
onChangeText = {(phone) => this.setState({phone})}
value = {this.state.phone}
autoCapitalize="none"
keyboardType='numeric'
returnKeyType={"next"}
maxLength = {10}
onSubmitEditing={(event) => this._password._root.focus()}
/>
</Item>
<Item floatingLabel>
<Label>Password</Label>
<Input
getRef={(c) => this._password = c}
onChangeText = {(password) => this.setState({password})}
value={this.state.password}
autoCapitalize="none"
returnKeyType={"done"}
secureTextEntry={this.state.hiddenPassword}
onSubmitEditing = {this.handleLogin}
/>
</Item>
<TouchableOpacity>
<Button style={styles.Button}
onPress={this.handleLogin.bind(this)}>
<Text style={styles.buttonText}>
LOGIN
</Text>
</Button>
</TouchableOpacity>
This is basically a TextInput Wrapper from React Native, if what you want to do is that when you press the "next" button, go to the other input you should do the following.
// <AuthField> render function
<Item>
<Input
value={value}
onChangeText={onChangeText}
placeholder={placeholder}
autoCorrect={false}
secureTextEntry={secureTextEntry}
returnKeyType={returnKeyType}
{ ...this.props }
/>
</Item>
And in your Component you can use it in this way:
// Other render
<Form style={styles.formStyle}>
<AuthFieldInput
placeholder="Username or Email"
value={this.state.username}
onChangeText={username => this.setState({username})}
returnKeyType="next"
onSubmitEditing={() => {
this.refs.passwowrd.focus();
}}
/>
<AuthFieldInput
ref='password'
placeholder="Password"
value={this.state.password}
onChangeText={password => this.setState({password})}
secureTextEntry
returnKeyType="go"
/>
</Form>
Update:
Please check the documentation about this feature https://facebook.github.io/react-native/docs/textinput.html#onsubmitediting
It seems that those return types do not do that. This question was asked before also:
React Native: How to select the next TextInput after pressing the "next" keyboard button?
Maybe it can be of some help to you!
I have an issue with onChangeText in password input. Detail explanation for what i want to do: I want to disable submit button initially and when both input field filled then enable submit button. If you have any other ways to solve this please share.
<InputGroup style={styles.inputBox}>
<Icon name='ios-person' style={{color: 'white'}}/>
<Input placeholder='Email' style={styles.input}
placeholderTextColor='rgba(255, 255, 255, 0.6)'
value={this.state.username}
onChangeText={(text) => this.setState({username: text})}
onChange={this.onInputChange} />
</InputGroup>
<InputGroup style={styles.inputBox}>
<Icon name='ios-unlock' style={{color: 'white'}}/>
<Input placeholder='Password' style={styles.input}
secureTextEntry={true}
placeholderTextColor='rgba(255, 255, 255, 0.6)'
value={this.state.password}
onChangeText={(text) => this.setState({password: text})}
onChange={this.onInputChange} />
</InputGroup>
<Button block bordered success style={styles.submitButton} onPress={this.onSignIn} disabled={this.state.submitButtonFlag}>
Sign In
</Button>
code for onChangeInput:
onInputChange() {
if (this.state.username != null && this.state.password != null) {
console.log("this.state.submitButtonFlag: ");
this.setState = {submitButtonFlag: false};
console.log(this.state.submitButtonFlag);
}
}
Two errors:
reference with correct this scope: onChange={() => this.onInputChange()} />
setState is a function: this.setState({submitButtonFlag: false});
You need to bind your method that you are calling or use callback like #zvona mentioned
First way
onChange={this.onInputChange.bind(this)}
Second Way
onChange={() => this.onInputChange()}