React Native: How to select the next TextInput after pressing the "next" keyboard button?
Solution 1:
Set the second TextInput
focus, when the previous TextInput
's onSubmitEditing
is triggered.
Try this
Adding a Ref to second TextInput
ref={(input) => { this.secondTextInput = input; }}
Bind focus function to first TextInput's onSubmitEditing event.
onSubmitEditing={() => { this.secondTextInput.focus(); }}
Remember to set blurOnSubmit to false, to prevent keyboard flickering.
blurOnSubmit={false}
When all done, it should looks like this.
<TextInput
placeholder="FirstTextInput"
returnKeyType="next"
onSubmitEditing={() => { this.secondTextInput.focus(); }}
blurOnSubmit={false}
/>
<TextInput
ref={(input) => { this.secondTextInput = input; }}
placeholder="secondTextInput"
/>
Solution 2:
Thought I would share my solution using a function component... 'this' not needed!
React 16.12.0 and React Native 0.61.5
Here is an example of my component:
import React, { useRef } from 'react'
...
const MyFormComponent = () => {
const ref_input2 = useRef();
const ref_input3 = useRef();
return (
<>
<TextInput
placeholder="Input1"
autoFocus={true}
returnKeyType="next"
onSubmitEditing={() => ref_input2.current.focus()}
/>
<TextInput
placeholder="Input2"
returnKeyType="next"
onSubmitEditing={() => ref_input3.current.focus()}
ref={ref_input2}
/>
<TextInput
placeholder="Input3"
ref={ref_input3}
/>
</>
)
}
Solution 3:
You can do this without using refs. This approach is preferred, since refs can lead to fragile code. The React docs advise finding other solutions where possible:
If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.
Instead, we'll use a state variable to focus the second input field.
-
Add a state variable that we'll pass as a prop to the
DescriptionInput
:initialState() { return { focusDescriptionInput: false, }; }
-
Define a handler method that will set this state variable to true:
handleTitleInputSubmit() { this.setState(focusDescriptionInput: true); }
-
Upon submitting / hitting enter / next on the
TitleInput
, we'll callhandleTitleInputSubmit
. This will setfocusDescriptionInput
to true.<TextInput style = {styles.titleInput} returnKeyType = {"next"} autoFocus = {true} placeholder = "Title" onSubmitEditing={this.handleTitleInputSubmit} />
-
DescriptionInput
'sfocus
prop is set to ourfocusDescriptionInput
state variable. So, whenfocusDescriptionInput
changes (in step 3),DescriptionInput
will re-render withfocus={true}
.<TextInput style = {styles.descriptionInput} multiline = {true} maxLength = {200} placeholder = "Description" focus={this.state.focusDescriptionInput} />
This is a nice way to avoid using refs, since refs can lead to more fragile code :)
EDIT: h/t to @LaneRettig for pointing out that you'll need to wrap the React Native TextInput with some added props & methods to get it to respond to focus
:
// Props:
static propTypes = {
focus: PropTypes.bool,
}
static defaultProps = {
focus: false,
}
// Methods:
focus() {
this._component.focus();
}
componentWillReceiveProps(nextProps) {
const {focus} = nextProps;
focus && this.focus();
}