Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 8821

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T04:41:08+00:00 2024-11-28T04:41:08+00:00

Mutable and immutable useRef semantics with React & TypeScript

  • 60k

In this post, you will learn how different ways declaring a ref with useRef hook influence the immutability of the current ref property. We will be looking at how to make the current property immutable, mutable, and know without much effort if the ref is one or the other.

All the behavior I'm going to talk about is only relevant in the context of TypeScript. The mutability / immutability is enforced at type level, not runtime level.

Immutable current property

The immutable semantics of the useRef hooks are usually used with DOM elements. A common use-case might be to get the ref of an element and focus that element whenever a button is clicked.

Here is how I would write that.

import * as React from "react";  const Component = () => {   const inputRef = React.useRef<HTMLInputElement>(null);    return (     <div>       <input type="text" name="name" ref={inputRef} />       <button type="button" onClick={() => inputRef.current?.focus()}>         Click to focus the input       </button>     </div>   ); }; 
Enter fullscreen mode Exit fullscreen mode

Notice the type and the value I’ve initialized the useRef with. The semantics I’ve used signal that I’m relying on React to manage the ref for me. In our case, this means that I cannot mutate the inputRef.current. If I ever tried to do that, TypeScript would complain.

import * as React from "react";  const Component = () => {   const inputRef = React.useRef<HTMLInputElement>(null);     return (     <div>         {/* Cannot assign to 'current' because it is a read-only property */}       <input type = "text" ref = {callbackRefValue => inputRef.current = callbackRefValue}>       <button type="button" onClick={() => inputRef.current?.focus()}>         Click to focus the input       </button>     </div>   ); }; 
Enter fullscreen mode Exit fullscreen mode

After writing similar code for a while, I’ve created a rule of thumb I follow to understand if the ref that I’m looking is immutable.

If the useRef is initialized with null and the initial value does not belong to the provided type, the current property is immutable.

In our case, the null initial value does not belong to the type HTMLInputElement so the current property cannot be mutated.

Mutable current property

To have the current property of the ref be mutable, we need to change how we are declaring ref itself.

Suppose we are writing a component that deals with timers. The useRef hook is an ideal candidate to hold a reference to a timer. With the timer reference at hand, we can make sure that we clear the timer when the component unmounts.

Here is an, albeit a bit contrived, example.

import * as React from "react";  const Component = () => {   const timerRef = React.useRef<number | null>(null);   // This is also a valid declaration   // const timerRef = React.useRef<number>()      React.useEffect(() => {         // Mutation of the `current` property         timerRef.current = setTimeout(/* ... */)         return clearInterval(timerRef.current)     }, [])    return (       // ...   ); }; 
Enter fullscreen mode Exit fullscreen mode

Since in the beginning, I have no way to know what the reference to the later declared setTimeout might be, I've initialized the useRef with null. Apart from the types, the declaration of the ref might seem eerily similar to the one in the Immutable current property section.
However, since the initially provided value (in our case null) wholly belongs to the type I've declared the useRef with (number | null), the current property is allowed to be mutable.

Similarly to the immutable current property case, here is my rule of thumb.

If the useRef is initialized with a value that belongs to the provided type, the current property of the ref is mutable.

In our case, the null initial value belongs to the type number | null so the current property can be mutated.
As an alternative, I could have declared the timerRef variable the following way

const timerRef = React.useRef<number>(); // the `timerRef.current` is also mutable 
Enter fullscreen mode Exit fullscreen mode

Why is the current allowed to be mutated in this case? Because the timerRef is implicitly initialized with the undefined value. The undefined value belongs to the type I've declared the timerRef – the React.useRef typings are overloaded depending on the type of the initial value.

const timerRef = React.useRef<number>();  // Really is const timerRef = React.useRef<number>(undefined);  // The `React.useRef` type definitions specify an overload whenever the type of the initial value is `undefined` function useRef<T = undefined>(): MutableRefObject<T | undefined>; // Notice the `MutableRefObject`. 
Enter fullscreen mode Exit fullscreen mode

Summary

When I started working with React & TypeScript, I found the difference between mutable and immutable refs quite confusing. I hope that this article was helpful and cleared some of the questions you might have had on the subject matter.

You can find me on twitter – @wm_matuszewski.

Thank you for your time.

hooksreacttypescriptwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.