How to Programmatically Set Focus to TextInput in React Native: A Complete Guide
Use a ref to access the TextInput component and call the .focus() method, which React Native forwards to the native platform via the TextInputState module.
When building forms in React Native, you often need to programmatically set focus to a TextInput component to guide user input or create custom navigation flows. According to the facebook/react source code, this is accomplished through a ref-based API that delegates focus commands to the native renderer via the TextInputState module.
Understanding the Focus Architecture in React Native
React Native's TextInput is a host component that maps to native views like RCTTextInput on iOS or AndroidTextInput on Android. When you call .focus() on a TextInput ref, the request flows through several layers of the React Native renderer.
In packages/react-native-renderer/src/ReactNativeFiberHostComponent.js, the host component implements the focus() method at lines 54-56:
focus() {
TextInputState.focusTextInput(this);
}
This delegates the actual focus operation to the TextInputState module, which interfaces with the platform-specific native code to make the input field the first responder.
How to Programmatically Set Focus Using Refs
To programmatically set focus to TextInput in React Native, you need to create a ref, attach it to the TextInput component, and call the focus() method on that ref.
Functional Component with Hooks
Here is a complete example using React hooks and functional components:
import React, {useRef, useEffect} from 'react';
import {TextInput, View, Button} from 'react-native';
export default function FocusDemo() {
const inputRef = useRef<TextInput>(null);
// Focus as soon as the component mounts
useEffect(() => {
inputRef.current?.focus();
}, []);
const focusOnPress = () => {
inputRef.current?.focus();
};
return (
<View>
<TextInput
ref={inputRef}
placeholder="Tap the button to focus"
style={{borderWidth: 1, padding: 8, margin: 10}}
/>
<Button title="Focus TextInput" onPress={focusOnPress} />
</View>
);
}
In this example, useRef creates a reference to the TextInput. The optional chaining operator ?. ensures safe access to the focus() method.
Class Component Approach
For class components, use React.createRef():
import React from 'react';
import {TextInput, View, TouchableOpacity, Text} from 'react-native';
export default class FocusDemoClass extends React.Component {
inputRef = React.createRef<TextInput>();
componentDidMount() {
// Optionally focus when the component appears
this.inputRef.current?.focus();
}
focusInput = () => {
this.inputRef.current?.focus();
};
render() {
return (
<View>
<TextInput
ref={this.inputRef}
placeholder="Press the box to focus"
style={{borderWidth: 1, padding: 8, margin: 10}}
/>
<TouchableOpacity onPress={this.focusInput}>
<Text>Focus TextInput</Text>
</TouchableOpacity>
</View>
);
}
}
Both approaches rely on the same underlying mechanism where the ref provides access to the host component's focus() method.
Key Source Files in the React Native Renderer
The programmatic focus functionality is implemented across several files in the facebook/react repository:
-
packages/react-native-renderer/src/ReactNativeFiberHostComponent.js: Contains thefocus()method at lines 54-56 that delegates toTextInputState.focusTextInput(this). -
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/TextInputState.js: Provides the mock implementation offocusTextInputandblurTextInputhelpers used by the renderer. -
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js: ExposesTextInputStateto the renderer internals. -
packages/react-native-renderer/src/ReactFiberConfigNative.js: Defines the native view types treated as text inputs (e.g.,AndroidTextInput,RCTMultilineTextInputView) at lines 276-278.
These files demonstrate how React Native bridges JavaScript focus calls to native platform APIs.
Summary
-
To programmatically set focus to TextInput in React Native, create a ref using
useReforcreateRef, attach it to the TextInput component, and callref.current.focus(). -
The
focus()method is implemented inReactNativeFiberHostComponent.jsand delegates to theTextInputStatemodule, which interfaces with native platform APIs. -
This approach works identically in both functional components with hooks and class components.
-
The underlying architecture treats TextInput as a host component that maps to native views like
RCTTextInput(iOS) orAndroidTextInput(Android).
Frequently Asked Questions
How do I autofocus a TextInput when the screen loads?
Use the useEffect hook with an empty dependency array to trigger focus after the component mounts. Call inputRef.current?.focus() inside the effect. This ensures the native view has been created before attempting to set focus.
Why is my TextInput not focusing programmatically?
Common causes include calling focus() before the component mounts, the ref not being properly attached to the TextInput, or the input being inside a modal or overlay that hasn't finished rendering. Ensure you use optional chaining (?.) and trigger focus after mount using useEffect or componentDidMount.
Can I programmatically blur a TextInput as well?
Yes. React Native provides a .blur() method on the TextInput ref that works identically to .focus(). According to the source code in ReactNativeFiberHostComponent.js, the blur() method delegates to TextInputState.blurTextInput(this), removing focus from the native input.
Does this work with third-party input libraries?
Most third-party React Native input libraries expose the same ref-based API and forward refs to the underlying native TextInput. You can typically call .focus() on their refs as well, though you should verify the library's documentation to ensure proper ref forwarding to the host component.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →