React Native

Understanding Refs in React Native

April 26, 20243 min read
Cows with ear tags
Photo by Jenny Hill

In React Native, refs (references) provide a way to access the underlying components created in the render method. While the fundamental concept and utility of refs are shared between React for the web and React Native, their applications can vary slightly due to the different elements being manipulated (DOM nodes on the web vs. native components in React Native).

Purpose of Refs

Refs are used in React Native for several purposes:

  1. Directly Accessing a Component: Refs allow you to directly access a native or composite component, enabling you to interact with it in ways that aren't possible through the typical data flow (props and state).

  2. Managing Focus, Text Selection, or Media Playback: For example, you might use refs to programmatically focus a text input or play a video.

  3. Imperative Animations: While declarative handling of animations is preferred in React Native using the Animated API, refs can be used to trigger animations directly.

  4. Integration with Third-Party DOM Libraries: If integrating React Native Web or similar, refs might be necessary to manipulate DOM elements directly, though this use is more common in web development.

Creating Refs

Refs can be created using React.createRef() and attached to React elements via the ref attribute.

Example: Using createRef in a Class Component

import React, { Component } from 'react';
import { TextInput, Button } from 'react-native';

class TextInputWithFocusButton extends Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  focusTextInput = () => {
    // Directly focus the text input using the raw DOM API
    if (this.inputRef.current) {
      this.inputRef.current.focus();
    }
  };

  render() {
    return (
      <>
        <TextInput ref={this.inputRef} />
        <Button title="Focus the text input" onPress={this.focusTextInput} />
      </>
    );
  }
}

Using Hooks with Refs

In functional components, useRef() is more commonly used to create refs. Unlike createRef, useRef gives you the same ref object on every render.

Example: Using useRef in a Functional Component

import React, { useRef } from 'react';
import { TextInput, Button } from 'react-native';

function TextInputWithFocusButton() {
  const inputRef = useRef(null);

  const focusTextInput = () => {
    inputRef.current && inputRef.current.focus();
  };

  return (
    <>
      <TextInput ref={inputRef} />
      <Button title="Focus the text input" onPress={focusTextInput} />
    </>
  );
}

Callback Refs

Another way to set refs is by using callback refs. This approach provides more flexibility and can be useful in certain scenarios, such as when you need to set the ref conditionally or integrate with other libraries.

Example of a Callback Ref

import React from 'react';
import { TextInput, Button } from 'react-native';

class CustomTextInput extends React.Component {
  setTextInputRef = element => {
    this.textInput = element;
  };

  focusTextInput = () => {
    // Focus the text input using the raw DOM API
    if (this.textInput) {
      this.textInput.focus();
    }
  };

  render() {
    return (
      <>
        <TextInput ref={this.setTextInputRef} />
        <Button title="Focus the text input" onPress={this.focusTextInput} />
      </>
    );
  }
}

Best Practices

  • Avoid Overuse: Use refs sparingly. They can make your code harder to understand and lead to a more imperative coding style, which conflicts with React's declarative nature.
  • Encapsulation: If you find yourself using refs often, consider whether you should be using state or props to handle the behavior that you are implementing.
  • Cleanup: If your ref attaches to an event listener or initiates a subscription, ensure to clean up in the component's unmount phase to prevent memory leaks.

Refs provide powerful capabilities in React Native for managing focus, reading values, or triggering imperative animations, but they should be used judiciously within the larger context of React's declarative and component-based architecture.


React NativeRefsImperative