Refs

Loading concept...

React Refs: Your Secret Backdoor to the DOM

The Story of the Magic Name Tag

Imagine you’re at a huge birthday party with 100 kids. Everyone is wearing the same outfit! How do you find your best friend Tommy quickly?

Simple! You give Tommy a special name tag that only you know about. Now, no matter where Tommy goes, you can always find him instantly.

That’s exactly what useRef does in React!

It’s like a secret name tag you put on something. React won’t lose it, and you can always find it again.


What is useRef?

const myRef = useRef(null);

Think of useRef as a sticky note that:

  • Remembers something for you
  • Never causes the screen to re-draw
  • Stays the same forever (until you change it)

The Magic Box Analogy

Imagine a magic box on your desk:

  • You can put anything inside (a number, a toy, anything!)
  • The box stays there forever
  • Looking inside doesn’t change anything
  • Only YOU can change what’s inside
// Create a magic box (starts empty)
const myBox = useRef(null);

// Later, put something inside
myBox.current = "Hello!";

// Look inside anytime
console.log(myBox.current); // "Hello!"

The .current part is like opening the box to see inside.


DOM Access with Refs

Finding Tommy at the Party

Remember Tommy with the name tag? In React, HTML elements are like kids at a party. You can tag one!

function FocusInput() {
  // Create the name tag
  const inputRef = useRef(null);

  function handleClick() {
    // Find Tommy (the input) and focus it!
    inputRef.current.focus();
  }

  return (
    <div>
      {/* Put the name tag on this input */}
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the Input!
      </button>
    </div>
  );
}

What happens:

  1. We create a ref (name tag)
  2. We attach it to the input using ref={inputRef}
  3. When button is clicked, we find the input and focus it!

Real-Life Uses

Action Code
Focus an input inputRef.current.focus()
Scroll to element divRef.current.scrollIntoView()
Read value inputRef.current.value
Measure size divRef.current.offsetHeight

Forwarding Refs

The Mailman Problem

Imagine your friend lives inside a building. You can’t just knock on the building - you need someone to forward your letter to the right apartment!

In React, when you create a custom component, it’s like a building. The ref can’t find the input inside automatically.

graph TD A[You with a Letter] --> B[Building Entrance] B --> C[Mailman forwards it] C --> D[Your Friend's Door]

The Solution: forwardRef

import { forwardRef, useRef } from 'react';

// The Building that knows how to forward
const FancyInput = forwardRef((props, ref) => {
  return (
    <input
      ref={ref}
      className="fancy"
      {...props}
    />
  );
});

// Using it from outside
function App() {
  const inputRef = useRef(null);

  return (
    <div>
      <FancyInput ref={inputRef} />
      <button onClick={() => inputRef.current.focus()}>
        Focus!
      </button>
    </div>
  );
}

The magic spell: forwardRef wraps your component and passes the ref through!


Ref as Prop

The Simple Way (When forwardRef is Too Much)

Sometimes, you don’t need the fancy mailman. You can just pass the ref like any other prop!

// A simple component
function MyInput({ inputRef, label }) {
  return (
    <div>
      <label>{label}</label>
      <input ref={inputRef} />
    </div>
  );
}

// Using it
function App() {
  const nameRef = useRef(null);

  return (
    <MyInput
      inputRef={nameRef}
      label="Your Name"
    />
  );
}

Wait, why use this instead of forwardRef?

Method When to Use
forwardRef Standard libraries, reusable UI kits
Ref as prop Quick fixes, internal components

Think of it like:

  • forwardRef = Official mailman with uniform
  • Ref as prop = Your friend passing a note

useImperativeHandle

The Royal Butler

Imagine you have a royal butler. Instead of letting guests touch EVERYTHING in your house, the butler only shows them specific things.

useImperativeHandle = Your butler for refs!

It lets you say: “When someone uses my ref, only let them do THESE specific things.”

import {
  forwardRef,
  useRef,
  useImperativeHandle
} from 'react';

const FancyInput = forwardRef((props, ref) => {
  // The REAL input ref (hidden inside)
  const realInputRef = useRef(null);

  // The butler: only expose these methods
  useImperativeHandle(ref, () => ({
    focus: () => {
      realInputRef.current.focus();
    },
    shake: () => {
      realInputRef.current.style.animation =
        'shake 0.5s';
    }
  }));

  return <input ref={realInputRef} />;
});

Now when someone uses your component:

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

  return (
    <div>
      <FancyInput ref={inputRef} />

      {/* These work! Butler allows them */}
      <button onClick={() => inputRef.current.focus()}>
        Focus
      </button>
      <button onClick={() => inputRef.current.shake()}>
        Shake!
      </button>

      {/* This WON'T work! Butler hides it */}
      {/* inputRef.current.value is undefined */}
    </div>
  );
}

Why Use the Butler?

graph TD A[Without useImperativeHandle] --> B[Everyone sees everything] A --> C[Easy to break things] D[With useImperativeHandle] --> E[Only show what you want] D --> F[Safe and controlled]

Quick Summary: All 5 Concepts

Concept What It Does Analogy
useRef Creates a persistent box Magic box on your desk
DOM Access Tags and finds elements Name tag at a party
forwardRef Passes refs through components Mailman in a building
Ref as prop Simple ref passing Friend passing a note
useImperativeHandle Controls what ref exposes Royal butler

The Complete Picture

graph TD A[useRef Hook] --> B[Store Values] A --> C[Access DOM] C --> D[Direct ref] C --> E[forwardRef] C --> F[Ref as prop] E --> G[useImperativeHandle] style A fill:#f9f,stroke:#333 style G fill:#9ff,stroke:#333

You Did It!

Now you understand React Refs like a pro:

  1. useRef = Your magic box that remembers
  2. DOM Access = Finding Tommy at the party
  3. forwardRef = The mailman who forwards letters
  4. Ref as prop = Passing notes to friends
  5. useImperativeHandle = Your royal butler

You’re ready to control the DOM like a wizard!

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.