DEV Community

Cover image for Access a component's underlying DOM node with findDOMNode()
Phuoc Nguyen
Phuoc Nguyen

Posted on • Updated on • Originally published at phuoc.ng

Access a component's underlying DOM node with findDOMNode()

When working with React, we often use the virtual DOM instead of the real DOM because updating the virtual DOM is much faster than updating the real DOM directly. However, there are times when we need to access the real DOM node. For example, we may need to measure its dimensions or apply a third-party library that requires direct manipulation of the DOM. In these cases, we can use the ReactDOM.findDOMNode() method to get a reference to the underlying DOM node for a given component instance.

Although findDOMNode() was commonly used in the early days of React, it is now deprecated and not recommended for use in modern React applications. However, we still introduce it in this series to provide a complete understanding of React ref.

Understanding the syntax

The findDOMNode() function in React is straightforward. It only requires one parameter, which is the component you want to access the DOM node of.

import * as ReactDOM from 'react-dom';

ReactDOM.findDOMNode(component);
Enter fullscreen mode Exit fullscreen mode

Let's see the function in action. We'll create a component that automatically fits content of a text area. Exciting stuff! Let's dive into the next section.

Automatically resizing text areas

Auto-resizing text areas are a great feature for many real-life situations. For example, in comment sections on websites, users often write comments of different lengths. If the text area is fixed, it can be challenging to write or read longer comments. With an auto-resize feature, the text area can expand as the user types, making it more comfortable to write and read comments. As a result, there can be more engagement and discussion on the website.

Another use case is in forms where users need to provide input that may vary in length, such as feedback or descriptions. An auto-resize text area can make it easier for users to provide their input without feeling limited by a small text box. With auto-resize, users can write as much as they need to, making the process smoother and more enjoyable.

We're creating a component called AutoResizeTextarea that will resize the text area element to fit its initial value. We'll use the componentDidMount() lifecycle method to call the fit() function when the component is first mounted. This ensures that the textarea is sized correctly from the start. Don't worry, we'll go over the fit() function soon.

class AutoResizeTextarea extends React.Component {
    componentDidMount() {
        this.fit();
    }

    render() {
        return <textarea></textarea>;
    }
}
Enter fullscreen mode Exit fullscreen mode

In this component, the fit() method is responsible for resizing the textarea to fit its content. First, it grabs the DOM node using ReactDOM.findDOMNode(this) and sets its height to 'auto'. This tells the browser to calculate the necessary height based on the content of the textarea.

fit() {
    const textarea = ReactDOM.findDOMNode(this);
    textarea.style.height = 'auto';
}
Enter fullscreen mode Exit fullscreen mode

Next, we need to figure out the border width at the top and bottom of the textarea. To do this, we retrieve the computed styles of the textarea and pass the border width values to the parseValue() method.

const styles = window.getComputedStyle(textarea);

const borderTopWidth = this.parseValue(styles.borderTopWidth);
const borderBottomWidth = this.parseValue(styles.borderBottomWidth);
Enter fullscreen mode Exit fullscreen mode

parseValue() is a helper method takes a CSS value as a string and returns its integer value in pixels. If the value ends with 'px', we convert it to an integer using parseInt(). Otherwise, we return 0 as the default value.

parseValue(v) {
    return v.endsWith('px') ? parseInt(v.slice(0, -2), 10) : 0;
}
Enter fullscreen mode Exit fullscreen mode

Once we have the border width values, we add them to the calculated height of the textarea before setting it as its new height. This ensures that the entire content of the textarea is visible without any overflow or cropping due to borders.

fit() {
    // ...
    textarea.style.height = `${textarea.scrollHeight + borderTopWidth + borderBottomWidth}px`;
}
Enter fullscreen mode Exit fullscreen mode

Resizing the text area automatically as users change its value is a piece of cake. We simply need to handle the input event that triggers whenever users modify the value, and call the fit() function within the handler.

class AutoResizeTextarea extends React.Component {
    handleInput(e) {
        this.fit();
    }

    render() {
        return <textarea onInput={this.handleInput}></textarea>;
    }
}
Enter fullscreen mode Exit fullscreen mode

Let's take a look at how we can use the component we created earlier:

Limitations of findDOMNode()

findDOMNode() is no longer recommended for use in modern React applications due to its limitations. One of its limitations is that it can only be used on class components, not functional components. This means that if you're using functional components, you'll need to switch to class components or find another way to access the underlying DOM node.

Another limitation is that findDOMNode() can only be called after a component has mounted. If you need to access the DOM node before it has mounted, you'll need to find another way to do so.

Using findDOMNode() can also lead to performance issues because it breaks the separation between the virtual DOM and the real DOM. When we update the virtual DOM, React uses a diffing algorithm to determine which parts of the real DOM need to be updated. However, when we use findDOMNode(), we bypass this algorithm and directly manipulate the real DOM, which can lead to unnecessary updates and slower performance.

Finally, findDOMNode() only gives access to the root DOM node representing the component. If you want to access different elements within the component, you'll need to find another solution. In the next post, we'll discuss an alternative solution using string refs.


It's highly recommended that you visit the original post to play with the interactive demos.

If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me:

Top comments (0)