HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptreactCritical

What's the difference between `useRef` and `createRef`?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
whatusereftheanddifferencecreaterefbetween

Problem

I was going through the hooks documentation when I stumbled upon useRef.

Looking at their example…

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      
      Focus the input
    
  );
}


…it seems like useRef can be replaced with createRef.

function TextInputWithFocusButton() {
  const inputRef = createRef(); // what's the diff?
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputRef.current.focus();
  };
  return (
    <>
      
      Focus the input
    
  );
}


Why do I need a hook for refs? Why does useRef exist?

Solution

The difference is that createRef will always create a new ref. In a class-based component, you would typically put the ref in an instance property during construction (e.g. this.input = createRef()). You don't have this option in a function component. useRef takes care of returning the same ref each time as on the initial rendering.

Here's an example app demonstrating the difference in the behavior of these two functions:

import React, { useRef, createRef, useState } from "react";
import ReactDOM from "react-dom";

function App() {
  const [renderIndex, setRenderIndex] = useState(1);
  const refFromUseRef = useRef();
  const refFromCreateRef = createRef();
  if (!refFromUseRef.current) {
    refFromUseRef.current = renderIndex;
  }
  if (!refFromCreateRef.current) {
    refFromCreateRef.current = renderIndex;
  }
  return (
    
      Current render index: {renderIndex}
      
      First render index remembered within refFromUseRef.current:
      {refFromUseRef.current}
      
      First render index unsuccessfully remembered within
      refFromCreateRef.current:
      {refFromCreateRef.current}
      
       setRenderIndex(prev => prev + 1)}>
        Cause re-render
      
    
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(, rootElement);

Code Snippets

import React, { useRef, createRef, useState } from "react";
import ReactDOM from "react-dom";

function App() {
  const [renderIndex, setRenderIndex] = useState(1);
  const refFromUseRef = useRef();
  const refFromCreateRef = createRef();
  if (!refFromUseRef.current) {
    refFromUseRef.current = renderIndex;
  }
  if (!refFromCreateRef.current) {
    refFromCreateRef.current = renderIndex;
  }
  return (
    <div className="App">
      Current render index: {renderIndex}
      <br />
      First render index remembered within refFromUseRef.current:
      {refFromUseRef.current}
      <br />
      First render index unsuccessfully remembered within
      refFromCreateRef.current:
      {refFromCreateRef.current}
      <br />
      <button onClick={() => setRenderIndex(prev => prev + 1)}>
        Cause re-render
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Context

Stack Overflow Q#54620698, score: 319

Revisions (0)

No revisions yet.