Understanding `div` Refs in TypeScript

In modern web development, React with TypeScript has become a popular choice for building user interfaces. When working with DOM elements like <div> in React applications, refs play a crucial role. Refs provide a way to access and interact with DOM nodes directly. This blog post will delve into the fundamental concepts of using div refs in TypeScript, cover their usage methods, common practices, and best practices.

Table of Contents

  1. Fundamental Concepts
  2. Usage Methods
  3. Common Practices
  4. Best Practices
  5. Conclusion
  6. References

Fundamental Concepts

What are Refs?

Refs in React are a way to access DOM nodes or React elements created in the render method. They are used when you need to perform actions directly on the DOM, such as focusing an input field, measuring the dimensions of an element, or integrating with third - party DOM libraries.

Types of Refs in React

  • String Refs (deprecated): This was the old way of creating refs in React. It is no longer recommended due to some limitations and performance issues.
  • Callback Refs: A function that gets called with the DOM node or React element as an argument. It can be used to store a reference to the element in a class property.
  • createRef: Introduced in React 16.3, it is a new way to create refs. It returns a mutable ref object whose .current property is initialized to null. The .current property will be set to the corresponding DOM node or React element when the component mounts and set to null when it unmounts.
  • useRef: A React Hook that allows you to create a mutable ref object in functional components. It works similarly to createRef but is used in functional components.

TypeScript and Refs

When using TypeScript with React, we need to specify the type of the ref object. For a div element, the type is HTMLDivElement.

Usage Methods

Using createRef in Class Components

import React, { Component } from 'react';

class DivRefExample extends Component {
    // Create a ref object with the type HTMLDivElement
    divRef = React.createRef<HTMLDivElement>();

    componentDidMount() {
        if (this.divRef.current) {
            // Access the DOM node and perform an action
            this.divRef.current.style.backgroundColor = 'lightblue';
        }
    }

    render() {
        return (
            <div ref={this.divRef}>
                This is a div with a ref.
            </div>
        );
    }
}

export default DivRefExample;

Using useRef in Functional Components

import React, { useRef, useEffect } from 'react';

const DivRefFunctionalExample = () => {
    // Create a ref object with the type HTMLDivElement
    const divRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        if (divRef.current) {
            // Access the DOM node and perform an action
            divRef.current.style.backgroundColor = 'lightgreen';
        }
    }, []);

    return (
        <div ref={divRef}>
            This is a div with a ref in a functional component.
        </div>
    );
};

export default DivRefFunctionalExample;

Using Callback Refs

import React from 'react';

const DivCallbackRefExample = () => {
    let divElement: HTMLDivElement | null = null;

    const setDivRef = (element: HTMLDivElement | null) => {
        divElement = element;
        if (divElement) {
            divElement.style.backgroundColor = 'lightyellow';
        }
    };

    return (
        <div ref={setDivRef}>
            This is a div with a callback ref.
        </div>
    );
};

export default DivCallbackRefExample;

Common Practices

Measuring Element Dimensions

import React, { useRef, useEffect } from 'react';

const MeasureDivDimensions = () => {
    const divRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        if (divRef.current) {
            const { width, height } = divRef.current.getBoundingClientRect();
            console.log(`Div width: ${width}, Div height: ${height}`);
        }
    }, []);

    return (
        <div ref={divRef} style={{ width: '200px', height: '100px', backgroundColor: 'pink' }}>
            Measure my dimensions.
        </div>
    );
};

export default MeasureDivDimensions;

Focusing an Element

import React, { useRef, useEffect } from 'react';

const FocusDiv = () => {
    const divRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        if (divRef.current) {
            divRef.current.tabIndex = 0;
            divRef.current.focus();
        }
    }, []);

    return (
        <div ref={divRef} style={{ border: '1px solid black' }}>
            This div will be focused on mount.
        </div>
    );
};

export default FocusDiv;

Best Practices

Null Checks

Always perform null checks before accessing the .current property of a ref. This is because the .current property can be null when the component has not yet mounted or has unmounted.

Avoid Overusing Refs

Refs should be used sparingly. They are intended for cases where you need to interact directly with the DOM. In most cases, you should rely on React’s declarative approach.

Keep Ref Logic Simple

The logic inside the ref callbacks or when accessing the ref’s .current property should be simple. Avoid complex calculations or side - effects that could be better handled in other parts of the component.

Conclusion

In conclusion, using div refs in TypeScript with React is a powerful way to interact with DOM elements directly. By understanding the fundamental concepts, different usage methods, common practices, and best practices, you can effectively use refs in your applications. Whether you are measuring element dimensions, focusing elements, or integrating with third - party libraries, refs provide a way to achieve these tasks. However, it’s important to use them judiciously and follow best practices to keep your code clean and maintainable.

References