Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. React Dictionary
  3. ref()

ref()

Since: React 16.8(2019)

A ref in React is an object that holds a reference to a DOM element or a class component instance. It takes the form { current: ... }, with the reference stored in the current property. In function components, refs are created with useRef; in class components, with React.createRef().

Structure of a ref Object

// A ref object is a plain object of the form { current: value }
const ref = { current: null };

// Passing it to the ref attribute in JSX causes React to set the DOM node into current after mount
<input ref={ref} />

// After mounting, access the DOM node via ref.current
ref.current; // The <input> DOM node
ref.current.focus(); // You can call DOM methods directly

// After unmounting, current is reset to null
ref.current; // null

Creation Methods

MethodOverview
useRef(initialValue)A hook used in function components. Returns the same ref object throughout the component's lifecycle. Can also be used to hold arbitrary values across renders, not just DOM references.
React.createRef()A method used in class components. Creates a new ref object each time it is called. Typically created in the constructor or as a class property with this.ref = React.createRef().
Callback refA method that passes a function to the ref attribute. The function is called with the DOM node at mount time and with null at unmount time. Useful when you need fine-grained control over when the ref is acquired.

Sample Code

This example demonstrates three ways to use refs: DOM access via useRef in a function component, createRef() in a class component, and a callback ref.

import { useRef, useEffect, createRef, Component } from 'react';

// -------------------------------------------------------
// 1. DOM access with useRef (function component)
// -------------------------------------------------------
function FocusExample() {
  // Create a ref object with useRef (initial value is null)
  // Returns an object { current: null }
  const inputRef = useRef(null);

  useEffect(function() {
    // After mounting, inputRef.current is set to the <input> DOM node
    // Call focus() to focus the input immediately on page load
    inputRef.current.focus();
  }, []);

  function handleShowValue() {
    // Access DOM properties directly through ref.current
    alert('Input value: ' + inputRef.current.value);
  }

  return (
    <div>
      {/* Pass the ref object to the ref attribute */}
      <input ref={inputRef} type="text" placeholder="Type here" />
      <button onClick={handleShowValue}>Check value</button>
    </div>
  );
}

// -------------------------------------------------------
// 2. DOM access with createRef() (class component)
// -------------------------------------------------------
class ClassFocusExample extends Component {
  constructor(props) {
    super(props);
    // Call createRef() in the constructor to create the ref
    // Storing it on this makes it reusable throughout the lifecycle
    this.inputRef = createRef();
  }

  handleClick() {
    // this.inputRef.current holds the <input> DOM node
    this.inputRef.current.focus();
  }

  render() {
    return (
      <div>
        <input ref={this.inputRef} type="text" placeholder="Class component example" />
        <button onClick={this.handleClick.bind(this)}>Focus</button>
      </div>
    );
  }
}

// -------------------------------------------------------
// 3. Callback ref
// -------------------------------------------------------
function CallbackRefExample() {
  // With a callback ref, you manage the variable that stores the ref yourself
  // Create a "container for the ref" using useRef
  const divRef = useRef(null);

  // Pass a function to the ref attribute
  // At mount: node receives the DOM node
  // At unmount: node receives null
  function callbackRef(node) {
    divRef.current = node;
    if (node !== null) {
      // Apply a style as soon as the DOM node is received
      node.style.border = '2px solid #61dafb';
    }
  }

  function handleClick() {
    if (divRef.current) {
      // Manipulate the DOM node obtained via the callback ref
      divRef.current.style.backgroundColor = '#e8f8ff';
    }
  }

  return (
    <div>
      {/* Passing a function to the ref attribute creates a callback ref */}
      <div ref={callbackRef} style={{ padding: '16px', display: 'inline-block' }}>
        Element managed by callback ref
      </div>
      <button onClick={handleClick}>Change background color</button>
    </div>
  );
}

// App displaying all three examples
function App() {
  return (
    <div style={{ padding: '16px' }}>
      <h2>Reference with useRef</h2>
      <FocusExample />

      <h2>Reference with createRef()</h2>
      <ClassFocusExample />

      <h2>Callback ref</h2>
      <CallbackRefExample />
    </div>
  );
}

export default App;

Overview

A ref is a simple object of the form { current: ... }, with the reference stored in the current property. When you pass this object to the ref attribute in JSX, React automatically sets the DOM node into current after mounting and resets it to null after unmounting.

When working with refs in function components, use useRef. Because useRef returns the same object throughout the component's lifecycle, it safely holds references across renders. In class components, use React.createRef(). Using createRef() in a function component creates a new object on every render, which is not appropriate.

A callback ref passes a function to the ref attribute and allows you to write logic that responds to the moment the ref is set or cleared. It is useful in cases where a static object is insufficient, such as dynamically managing references to each element of a list.

Ordinary function components cannot receive the ref attribute as a prop. To forward a ref to a child component, wrap it with forwardRef. To limit the API a child component exposes to its parent, combine it with useImperativeHandle.

Related pages: useRef / forwardRef / useImperativeHandle

Common Mistakes

Using createRef in a function component creates a new object on every render

In class components, React.createRef() is called inside the constructor to hold the ref. However, using createRef() in a function component creates a new ref object on every render, losing the reference to the previous DOM element. Use useRef in function components.

input_ng.jsx
import React from 'react';

function FocusInput({ label }) {
  // A new ref is created on every render, so current is always null
  const inputRef = React.createRef();

  function handleFocus() {
    inputRef.current.focus(); // current is null — will error
  }

  return (
    <div>
      <label>{label}</label>
      <input ref={inputRef} />
      <button onClick={handleFocus}>Focus</button>
    </div>
  );
}

function App() {
  return <FocusInput label="Kiryu Kazuma's input field" />;
}

Fixed:

input_ok.jsx
import { useRef } from 'react';

function FocusInput({ label }) {
  // useRef retains the same object across renders
  const inputRef = useRef(null);

  function handleFocus() {
    inputRef.current.focus();
  }

  return (
    <div>
      <label>{label}</label>
      <input ref={inputRef} />
      <button onClick={handleFocus}>Focus</button>
    </div>
  );
}

Reading or writing ref.current during rendering causes unstable behavior

Read and write refs inside event handlers or useEffect. Reading or writing ref.current during rendering (while JSX is being computed) interferes with React's re-rendering mechanism and leads to unpredictable behavior.

render_ref_ng.jsx
import { useRef } from 'react';

function Counter() {
  const countRef = useRef(0);

  // Mutating ref.current during rendering (wrong)
  countRef.current = countRef.current + 1;

  return <p>{countRef.current}</p>;
}

Fixed:

render_ref_ok.jsx
import { useRef } from 'react';

function Counter() {
  const countRef = useRef(0);

  // Mutate ref.current inside an event handler
  function handleClick() {
    countRef.current = countRef.current + 1;
    console.log('Click count:', countRef.current);
  }

  return <button onClick={handleClick}>Count (Majima Goro: {countRef.current})</button>;
}

If you find any errors or copyright issues, please .