Getting rid of findDOMNode in your React application

Clara Dopico
Trabe
Published in
4 min readMay 20, 2019
Photo by Annie Theby on Unsplash

Lately, our team has been migrating a project from React 16.2 to the latest version, 16.8. One of the challenges that we have encountered during this migration phase is the deprecation of findDOMNode. This ReactDOM method allows us to access the underlying DOM node of a component.

Using React StrictMode to check potential problems in our application, we ran into log warnings about our findDOMNode usages:

StrictMode warning messages

As we can see, findDOMNode is deprecated in StrictMode. Its usage is discouraged and, possibly, it will be deleted in a future version. The warning message recommends us to add a ref directly to the element we want to reference. But sometimes, when you are migrating a complex application, the solution may not be that simple. In some cases, for example, your components are formed only by other components, there is no DOM element (such as div or span) where to attach the ref.

Using findDOMNode this was not a problem. You could pass directly this or add a ref to any React component to retrieve the corresponding DOM element:

Simplify findDOMNode usage

So let’s go over the different solutions we have come across while trying to get rid of our findDOMNode usages.

Adding a DOM node wrapper

The simplest solution to this type of scenario is to wrap your component with a DOM element that you can actually attach a ref to it. For example:

The drawback of this solution is that it can get very tricky when you’re migrating a large application. For example, having many nested components positioned relative to each other can lead you to a CSS nightmare.

Using ref forwarding

Another solution that the React documentation recommends us is to pass a ref to your custom component and pass that along to the DOM using ref forwarding. This way it is not necessary to wrap our components or add new HTML elements.

Applied to our previous example:

The problem we can encounter using this approach is that it can lead us to the problem of the broken ref. As my colleague Ceci García García explained in her post, A better way of using refs in React, in case our component needs to be wrapped by other custom components or third-party libraries the ref will be lost. We will not be able to access that value anymore.

A typical case in our application that led us to a broken ref situation was how to position components like dropdowns or tooltips. That kind of component renders in a different layer in a determined location. In those cases, we need to retrieve the DOM node to get information like the element size or relative position to the viewport to locate them. We solved this by creating some HOCs that inject the size or the position to the components. One of them is the following example, used to inject the offsetParent to a component:

As we can see, this HOC wraps the component injecting its offsetParent as prop, a value that it obtains through findDOMNode(this). We can’t just replace it with a ref attached to WrappedComponent. We can’t wrap everything with a div or any other DOM element because it will lead us to some serious CSS drama. We shouldn’t use the forwardRef solution either, because it would not allow us to compose several HOCs or wrap the component with other components. So, how did we solve this?

Explicitly pass the ref as a prop to your component

The solution that we finally chose is to create a ref in the HOC but passing it through its wrapped component via props (domNodeRef in the example). Then, the final component will have the responsibility to attach it to an actual DOM element.

For example, injectOffset HOC is used by the Dropdown component. It receives as props both the offsetParent and the domNodeRef and attaches the latter to the corresponding div element:

The disadvantage of this method is that components that use our HOCs will need to know what to do with the domNodeRef they are receiving. But this solution allows us to wrap these components or use third-party libraries without fear of losing our ref.

Summing up

React findDOMNode method is already deprecated in StrictMode. It’s important to get rid of all its usages in our code to be ready to migrate to future React versions. The simplest solution is to replace it with a ref attached to the element we are interested in referencing (or a wrapper of it). But if we have to migrate an extensive and complex application this may not work for us in all cases. In those scenarios solutions like using ref forwarding or explicitly passing the ref as a prop can save us some tears.

--

--