Here is my code:
<Formik
initialValues={{
firstName: '',
lastName: ''
}}
onSubmit={values => alert(JSON.stringify(values))}
>
{props => (
<View>
<TextInput
value={props.values.firstName}
ref={ref => (this.firstName = ref)}
onSubmitEditing={() => {
this.lastName.focus()
}}
returnKeyType="next"
placeholder="input first name here"
{...props}
/>
<TextInput
value={props.values.lastName}
ref={ref => (this.lastName = ref)}
onSubmitEditing={handleSubmit}
placeholder="input last name here"
{...props}
/>
<Button onPress={props.handleSubmit} />
</View>
)}
</Formik>
When I press on Next button on virtual keyboard, my app will be crashing. How can I set next Input request focus in this case ?
Likely, this is not related to Formik, but to React Native
@Andreyco : if I render without Formik wrapper like:
<View>
<TextInput
value={this.state.firstName}
ref={ref => (this.firstName = ref)}
onSubmitEditing={() => {
this.lastName.focus()
}}
returnKeyType="next"
placeholder="input first name here"
/>
<TextInput
value={this.state.lastName}
ref={ref => (this.lastName = ref)}
onSubmitEditing={handleSubmit}
placeholder="input last name here"
/>
<Button onPress={handleSubmit} />
</View>
everything is working.
I've been using Formik successfully with onSubmitEditing and focusing the next field. The problem here seem that you're spreading the Formik render props to both inputs {...props}. This will try to bind focus/blur/onChange handlers but since the (RN) fields don't have name attributes they aren't bound properly
There's an example how to bind to react-native. For example we're using a custom input component that have a name prop and has useField
@kidroca Hi, could you please pass an example? im trying to do the same as you only im using <Field/> and adding a custom component so it currently looks like this (i created the refs in constructor of parent which is where the Field's components are at):
<Field
name="email"
label="Correo electr贸nico"
component={Input}
onChangeText={formikProps.handleChange('email')}
value={formikProps.values.email}
keyboardType="email-address"
touched={formikProps.touched.email}
errors={formikProps.errors.email}
returnKeyType="next"
onSubmitEditing={() => this.current.passwordInput.focus()}
innerRef={ (input) => { this.emailInput = input }}
onBlur={formikProps.handleBlur('email')}
/>
i saw somewhere that I had to pass innerRef as a prop to the custom component but dont really know how, or if what im doing needs to change in order to achieve the focus on next input on submitEditing. My custom component is just a normal text input with an icon styled next to it... any help from anyone is appreciated
im using: "formik": "^2.1.4",
You need to to forward the refs you create to the actual TextInput components
Something like this
import React from 'react';
import { TextInput, View } from 'react-native';
import { Formik, Field } from 'formik';
class SomeForm extends React.Component {
emailRef = React.createRef();
passwordRef = React.createRef();
render() {
return (
<Formik initialValues={{ email: '', password: '' }} onSubmit={(values) => console.log({ values })}>
<View>
<Field
name="email"
component={CustomField}
forwardRef={this.emailRef} // read this in the custom component and forward it to the desired ref
onSubmitEditing={() => this.passwordRef.current?.focus()} />
<Field
name="password"
component={CustomField}
forwardRef={this.passwordRef} />
</View>
</Formik>
);
}
}
const CustomField = (props) => (
<TextInput ref={ props.forwardRef } { ...props } />
);
The prop name can be anything innerRef is suitable too I chose forwardRef as we're forwarding the ref to the TextInput
There's also a React.forwardRef function that works in a similar way, but it's not as simple to explain, React.forwardRef is more beneficial when you want to write a library, when you write apps the above should work good enough
Also this is incorrect: onSubmitEditing={() => this.current.passwordInput.focus()}
It should probably be onSubmitEditing={() => this.passwordInput.current.focus()}
Most helpful comment
You need to to forward the refs you create to the actual
TextInputcomponentsSomething like this
The prop name can be anything
innerRefis suitable too I choseforwardRefas we're forwarding the ref to theTextInputThere's also a
React.forwardReffunction that works in a similar way, but it's not as simple to explain,React.forwardRefis more beneficial when you want to write a library, when you write apps the above should work good enoughAlso this is incorrect:
onSubmitEditing={() => this.current.passwordInput.focus()}It should probably be
onSubmitEditing={() => this.passwordInput.current.focus()}