The React useRef Hook: Not Just for HTML Elements

In React, state manages data that can trigger re-renders. But what if you need a way to directly access document object model (DOM) elements or persist values that shouldn’t cause re-renders? That’s where the useRef hook comes in.

Typically, you’d do …


This content originally appeared on DEV Community and was authored by Nick Taylor

In React, state manages data that can trigger re-renders. But what if you need a way to directly access document object model (DOM) elements or persist values that shouldn't cause re-renders? That's where the useRef hook comes in.

Typically, you'd do something like this.

import { useEffect, useRef } from "react";

export const SomeComponent = () => {
  const firstInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    firstInputRef.current?.focus();
  }, [firstInputRef.current]);

  return (
    <form>
      <label>
        Name:
        <input type="text" ref={firstInputRef}/>
      </label>
    </form>
  );
}
  1. We create a useRef named firstInputRef and initialize it with null (as it won't point to an element yet).
  2. The useEffect hook runs after the component renders.
  3. Inside useEffect, we check if firstInputRef.current exists (it will be the actual DOM element after the initial render). If it does, we call focus() to set focus on the input.
  4. The dependency array [firstInputRef.current] ensures useEffect only runs once when the reference changes (i.e., after the initial render).

In the above example, the useRef hook creates a reference object that holds a mutable value, the HTML element, but this value can be anything, from a DOM element to a plain object. Unlike state, changes to a useRef won't trigger a re-render of your component.

Recently, I was working on Open Sauced's StarSearch, a Copilot for git history feature we released at the end of May 2024.

The ask was to be able to start a new StarSearch conversation. To do so, I had to stop the current conversation. If you've worked with OpenAI or similar APIs, they typically stream a ReadableStream as a response.

I initially had this feature working, but ran into issues if the response started to stream. The solution, create a reference to the readable stream via the useRef hook and when a new conversation is started, cancel the one in progress. You can see these changes in the pull request (PR) below

fix: now a new StarSearch chat can be started if one was in progress #3637

Description

Now isRunning is reset to false when starting a new conversation. This was preventing the stream conversation from beginning when a previous one was cancelled and a new conversation started.

Related Tickets & Documents

Fixes #3636

Mobile & Desktop Screenshots/Recordings

Before

CleanShot 2024-06-25 at 21 25 35

After

CleanShot 2024-06-25 at 21 26 04

Steps to QA

  1. Go to any workspace and open StarSearch
  2. Start a conversation
  3. Cancel it by clicking the back button or new conversation buttons in the compact StarSearch header.
  4. Start the new conversation.
  5. Notice the new conversation streams in.

Tier (staff will fill in)

  • [ ] Tier 1
  • [ ] Tier 2
  • [ ] Tier 3
  • [x] Tier 4

[optional] What gif best describes this PR or how it makes you feel?

So now, if someone presses the create a new conversation button, I cancel the current streaming response from StarSearch, e.g.

  const streamRef = useRef<ReadableStreamDefaultReader<string>>();

...

  const onNewChat = () => {
    streamRef.current?.cancel();
    ...
  };

...

  1. We create a useRef named streamRef to hold the ReadableStreamDefaultReader.
  2. The onNewChat function checks if streamRef.current exists (meaning a stream is ongoing).
  3. If a stream exists, we call cancel() on streamRef.current to stop it before starting a new conversation.

useRef was the perfect solution for my use case. Maybe you'll find the useRef hook useful for something other than referencing an HTML element.

Stay saucy peeps!

If you would like to know more about my work in open source, follow me on OpenSauced.


This content originally appeared on DEV Community and was authored by Nick Taylor


Print Share Comment Cite Upload Translate Updates
APA

Nick Taylor | Sciencx (2024-07-08T04:38:17+00:00) The React useRef Hook: Not Just for HTML Elements. Retrieved from https://www.scien.cx/2024/07/08/the-react-useref-hook-not-just-for-html-elements/

MLA
" » The React useRef Hook: Not Just for HTML Elements." Nick Taylor | Sciencx - Monday July 8, 2024, https://www.scien.cx/2024/07/08/the-react-useref-hook-not-just-for-html-elements/
HARVARD
Nick Taylor | Sciencx Monday July 8, 2024 » The React useRef Hook: Not Just for HTML Elements., viewed ,<https://www.scien.cx/2024/07/08/the-react-useref-hook-not-just-for-html-elements/>
VANCOUVER
Nick Taylor | Sciencx - » The React useRef Hook: Not Just for HTML Elements. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/07/08/the-react-useref-hook-not-just-for-html-elements/
CHICAGO
" » The React useRef Hook: Not Just for HTML Elements." Nick Taylor | Sciencx - Accessed . https://www.scien.cx/2024/07/08/the-react-useref-hook-not-just-for-html-elements/
IEEE
" » The React useRef Hook: Not Just for HTML Elements." Nick Taylor | Sciencx [Online]. Available: https://www.scien.cx/2024/07/08/the-react-useref-hook-not-just-for-html-elements/. [Accessed: ]
rf:citation
» The React useRef Hook: Not Just for HTML Elements | Nick Taylor | Sciencx | https://www.scien.cx/2024/07/08/the-react-useref-hook-not-just-for-html-elements/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.