Skip to main content

findDOMNode

This API will be removed in a future major version of React. See the alternatives.

findDOMNode finds the browser DOM node for a React class component instance.

const domNode = findDOMNode(componentInstance)

Reference

findDOMNode(componentInstance)

Call findDOMNode to find the browser DOM node for a given React class component instance.

import { findDOMNode } from 'react-dom';

const domNode = findDOMNode(componentInstance);

See more examples below.

Parameters

  • componentInstance: An instance of the Component subclass. For example, this inside a class component.

Returns

findDOMNode returns the first closest browser DOM node within the given componentInstance. When a component renders to null, or renders false, findDOMNode returns null. When a component renders to a string, findDOMNode returns a text DOM node containing that value.

Caveats

  • A component may return an array or a Fragment with multiple children. In that case findDOMNode, will return the DOM node corresponding to the first non-empty child.

  • findDOMNode only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling findDOMNode() in render() on a component that has yet to be created), an exception will be thrown.

  • findDOMNode only returns the result at the time of your call. If a child component renders a different node later, there is no way for you to be notified of this change.

  • findDOMNode accepts a class component instance, so it can't be used with function components.


Usage

Finding the root DOM node of a class component

Call findDOMNode with a class component instance (usually, this) to find the DOM node it has rendered.

class AutoselectingInput extends Component {
componentDidMount() {
const input = findDOMNode(this);
input.select()
}

render() {
return <input defaultValue="Hello" />
}
}

Here, the input variable will be set to the <input> DOM element. This lets you do something with it. For example, when clicking "Show example" below mounts the input, input.select() selects all text in the input:

import { useState } from 'react';
import AutoselectingInput from './AutoselectingInput.js';

export default function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>
Show example
</button>
<hr />
{show && <AutoselectingInput />}
</>
);
}
import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
componentDidMount() {
const input = findDOMNode(this);
input.select()
}

render() {
return <input defaultValue="Hello" />
}
}

export default AutoselectingInput;

Alternatives

Reading component's own DOM node from a ref

Code using findDOMNode is fragile because the connection between the JSX node and the code manipulating the corresponding DOM node is not explicit. For example, try wrapping this <input /> into a <div>:

import { useState } from 'react';
import AutoselectingInput from './AutoselectingInput.js';

export default function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>
Show example
</button>
<hr />
{show && <AutoselectingInput />}
</>
);
}
import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
componentDidMount() {
const input = findDOMNode(this);
input.select()
}
render() {
return <input defaultValue="Hello" />
}
}

export default AutoselectingInput;

This will break the code because now, findDOMNode(this) finds the <div> DOM node, but the code expects an <input> DOM node. To avoid these kinds of problems, use createRef to manage a specific DOM node.

In this example, findDOMNode is no longer used. Instead, inputRef = createRef(null) is defined as an instance field on the class. To read the DOM node from it, you can use this.inputRef.current. To attach it to the JSX, you render <input ref={this.inputRef} />. This connects the code using the DOM node to its JSX:

import { useState } from 'react';
import AutoselectingInput from './AutoselectingInput.js';

export default function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>
Show example
</button>
<hr />
{show && <AutoselectingInput />}
</>
);
}
import { createRef, Component } from 'react';

class AutoselectingInput extends Component {
inputRef = createRef(null);

componentDidMount() {
const input = this.inputRef.current;
input.select()
}

render() {
return (
<input ref={this.inputRef} defaultValue="Hello" />
);
}
}

export default AutoselectingInput;

In modern React without class components, the equivalent code would call useRef instead:

import { useState } from 'react';
import AutoselectingInput from './AutoselectingInput.js';

export default function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>
Show example
</button>
<hr />
{show && <AutoselectingInput />}
</>
);
}
import { useRef, useEffect } from 'react';

export default function AutoselectingInput() {
const inputRef = useRef(null);

useEffect(() => {
const input = inputRef.current;
input.select();
}, []);

return <input ref={inputRef} defaultValue="Hello" />
}

Read more about manipulating the DOM with refs.


Reading a child component's DOM node from a forwarded ref

In this example, findDOMNode(this) finds a DOM node that belongs to another component. The AutoselectingInput renders MyInput, which is your own component that renders a browser <input>.

import { useState } from 'react';
import AutoselectingInput from './AutoselectingInput.js';

export default function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>
Show example
</button>
<hr />
{show && <AutoselectingInput />}
</>
);
}
import { Component } from 'react';
import { findDOMNode } from 'react-dom';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
componentDidMount() {
const input = findDOMNode(this);
input.select()
}
render() {
return <MyInput />;
}
}

export default AutoselectingInput;
export default function MyInput() {
return <input defaultValue="Hello" />;
}

Notice that calling findDOMNode(this) inside AutoselectingInput still gives you the DOM <input>--even though the JSX for this <input> is hidden inside the MyInput component. This seems convenient for the above example, but it leads to fragile code. Imagine that you wanted to edit MyInput later and add a wrapper <div> around it. This would break the code of AutoselectingInput (which expects to find an <input>).

To replace findDOMNode in this example, the two components need to coordinate:

  1. AutoSelectingInput should declare a ref, like in the earlier example, and pass it to <MyInput>.
  2. MyInput should be declared with forwardRef to take that ref and forward it down to the <input> node.

This version does that, so it no longer needs findDOMNode:

import { useState } from 'react';
import AutoselectingInput from './AutoselectingInput.js';

export default function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>
Show example
</button>
<hr />
{show && <AutoselectingInput />}
</>
);
}
import { createRef, Component } from 'react';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
inputRef = createRef(null);

componentDidMount() {
const input = this.inputRef.current;
input.select()
}

render() {
return (
<MyInput ref={this.inputRef} />
);
}
}

export default AutoselectingInput;
import { forwardRef } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
return <input ref={ref} defaultValue="Hello" />;
});

export default MyInput;

Here is how this code would look like with function components instead of classes:

import { useState } from 'react';
import AutoselectingInput from './AutoselectingInput.js';

export default function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>
Show example
</button>
<hr />
{show && <AutoselectingInput />}
</>
);
}
import { useRef, useEffect } from 'react';
import MyInput from './MyInput.js';

export default function AutoselectingInput() {
const inputRef = useRef(null);

useEffect(() => {
const input = inputRef.current;
input.select();
}, []);

return <MyInput ref={inputRef} defaultValue="Hello" />
}
import { forwardRef } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
return <input ref={ref} defaultValue="Hello" />;
});

export default MyInput;

Adding a wrapper <div> element

Sometimes a component needs to know the position and size of its children. This makes it tempting to find the children with findDOMNode(this), and then use DOM methods like getBoundingClientRect for measurements.

There is currently no direct equivalent for this use case, which is why findDOMNode is deprecated but is not yet removed completely from React. In the meantime, you can try rendering a wrapper <div> node around the content as a workaround, and getting a ref to that node. However, extra wrappers can break styling.

<div ref={someRef}>
{children}
</div>

This also applies to focusing and scrolling to arbitrary children.