Ref Hooks - rs-hash/Senior GitHub Wiki

useRef

useRef is a React Hook that lets you reference a value that’s not needed for rendering.

Changing a ref does not trigger a re-render

import { useRef } from 'react';

function MyComponent() {
  const intervalRef = useRef(0);
  const inputRef = useRef(null);
  // ...
  • you can store information between re-renders (unlike regular variables, which reset on every render).
  • Changing it does not trigger a re-render (unlike state variables, which trigger a re-render).
  • The information is local to each copy of your component (unlike the variables outside, which are shared).

Parameters

initialValue: The value you want the ref object’s current property to be initially. It can be a value of any type. This argument is ignored after the initial render.

Returns

useRef returns an object with a single property:

  • current: Initially, it’s set to the initialValue you have passed. You can later set it to something else. If you pass the ref object to React as a ref attribute to a JSX node, React will set its current property. On the next renders, useRef will return the same object.

Caveats

  • You can mutate the ref.current property. Unlike state, it is mutable. However, if it holds an object that is used for rendering (for example, a piece of your state), then you shouldn’t mutate that object.
  • When you change the ref.current property,React does not re-render your component. React is not aware of when you change it because a ref is a plain JavaScript object.
  • Do not write or read ref.current during rendering, except for initialization. This makes your component’s behavior unpredictable.
  • In Strict Mode, React will call your component function twice in order to help you find accidental impurities. This is development-only behavior and does not affect production. Each ref object will be created twice, but one of the versions will be discarded. If your component function is pure (as it should be), this should not affect the behavior.
  • Do not write or read ref.current during rendering.
  • React expects that the body of your component behaves like a pure function:
  • If the inputs (props, state, and context) are the same, it should return exactly the same JSX.

wrong

function MyComponent() {
  // ...
  // 🚩 Don't write a ref during rendering
  myRef.current = 123;
  // ...
  // 🚩 Don't read a ref during rendering
  return <h1>{myOtherRef.current}</h1>;
}

right ( You can read or write refs from event handlers or effects instead. )

function MyComponent() {
  // ...
  useEffect(() => {
    // ✅ You can read or write refs in effects
    myRef.current = 123;
  });
  // ...
  function handleClick() {
    // ✅ You can read or write refs in event handlers
    doSomething(myOtherRef.current);
  }
  // ...
}

Code

1.
import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}

// Focus DOM

import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

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

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}

//Exposing a ref to your own component

import { forwardRef, useRef } from 'react';

const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});

export default function Form() {
  const inputRef = useRef(null);

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

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
⚠️ **GitHub.com Fallback** ⚠️