By default, the React Native TextInput component does not automatically focus the next one once you hit "enter" on your virtual keyboard.
Let's say we have two input fields for a username and password. A pretty common design would be to automatically focus the password field once the user "finishes" typing in their username.
Note that this implementation will specifically be for React Native but you can apply the same idea in React.
// ...
render() {
return (
<TextInput
blurOnSubmit={false}
onSubmitEditing={() => this.passwordRef.focus()}
/>
<TextInput
ref={ref => this.passwordRef = ref}
/>
);
}
// ...
Here, we are only chaining together two inputs but you can use the same approach to chain as many inputs as you need.
We are using refs to keep references to our text inputs. We provide a callback to the ref
property that will receive the component instance (DOM node) and then assign it to an instance property.
Afterwards, we pass a callback to the onSubmitEditing property that will focus our desired input field once a user "submits" their input. The blurOnSubmit property will be useful if you want the virtual keyboard to persist across multiple inputs.
This is a work in progress but here is a (simplified) component I created for the purpose of chaining text inputs:
class Field extends Component {
static propTypes = {
blurOnSubmit: PropTypes.bool,
getRef: PropTypes.func,
keyboardType: PropTypes.oneOf(['numeric']),
label: PropTypes.string.isRequired,
nextField: PropTypes.node,
placeholder: PropTypes.string,
};
static defaultProps = {
blurOnSubmit: false,
getRef: null,
keyboardType: 'numeric',
placeholder: '',
nextField: null,
};
setInputRef = ref => {
this.inputRef = ref;
const { getRef } = this.props;
if (getRef) {
getRef(ref);
}
};
render() {
const {
blurOnSubmit,
keyboardType,
label,
nextField,
placeholder,
} = this.props;
return (
<View>
<Text onPress={() => this.inputRef.focus()}>{label}</Text>
<TextInput
blurOnSubmit={blurOnSubmit}
keyboardType={keyboardType}
onSubmitEditing={() => nextField && nextField.focus()}
placeholder={placeholder}
ref={this.setInputRef}
/>
</View>
);
}
}
This component also contains a "label" that will focus the text input when clicked on. Some improvements include adding props for handling submit and setting the value.
Here is an example of the Field
component being used:
// ...
render() {
const { passwordRef } = this.state;
return (
<View>
<Field
label="Username"
nextField={passwordRef}
placeholder="test@test.com"
/>
<Field
label="Password"
placeholder="password"
getRef={ref => this.setState({ passwordRef: ref })}
/>
</View>
);
}
// ...
Using refs
for focusing inputs is pretty useful. The implementation becomes a bit more difficult as you have child components but I believe the abstraction improves future maintainability.
To be honest, refs
were a confusing concept that I avoided. Not to state that I fully understand it now; but being put in a situation where I had to understand it enough was a great learning experience.
A bit philosophical but we tend grow the most during times of discomfort.
Currently working on compounded, a simple mobile compound interest calculator. Looking to solve a personal need and learn new technologies!