findDOMNode
findDOMNode
encontra o nó do DOM do navegador para uma instância de componente de classe do React.
const domNode = findDOMNode(componentInstance)
Referência
findDOMNode(componentInstance)
Chame findDOMNode
para encontrar o nó do DOM do navegador para uma dada instância de componente de classe do React.
import { findDOMNode } from 'react-dom';
const domNode = findDOMNode(componentInstance);
Parâmetros
componentInstance
: Uma instância da subclasseComponent
. Por exemplo,this
dentro de um componente de classe.
Retornos
findDOMNode
retorna o primeiro nó do DOM do navegador mais próximo dentro da componentInstance
dada. Quando um componente renderiza null
, ou renderiza false
, findDOMNode
retorna null
. Quando um componente renderiza uma string, findDOMNode
retorna um nó do DOM de texto contendo esse valor.
Ressalvas
-
Um componente pode retornar um array ou um Fragmento com múltiplos filhos. Nesse caso,
findDOMNode
retornará o nó do DOM correspondente ao primeiro filho não vazio. -
findDOMNode
só funciona em componentes montados (isto é, componentes que foram colocados no DOM). Se você tentar chamar isso em um componente que ainda não foi montado (como chamarfindDOMNode()
emrender()
em um componente que ainda não foi criado), uma exceção será lançada. -
findDOMNode
retorna apenas o resultado no momento da sua chamada. Se um componente filho renderiza um nó diferente mais tarde, não há como você ser notificado sobre essa mudança. -
findDOMNode
aceita uma instância de componente de classe, portanto não pode ser usado com componentes de função.
Uso
Encontrando o nó do DOM raiz de um componente de classe
Chame findDOMNode
com uma instância de componente de classe (geralmente, this
) para encontrar o nó do DOM que ele renderizou.
class AutoselectingInput extends Component {
componentDidMount() {
const input = findDOMNode(this);
input.select()
}
render() {
return <input defaultValue="Hello" />
}
}
Aqui, a variável input
será definida como o elemento DOM <input>
. Isso permite que você faça algo com ele. Por exemplo, ao clicar em “Mostrar exemplo” abaixo monta o input, input.select()
seleciona todo o texto no input:
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;
Alternativas
Lendo o próprio nó do DOM de um componente a partir de um ref
O código que usa findDOMNode
é frágil porque a conexão entre o nó JSX e o código que manipula o nó do DOM correspondente não é explícita. Por exemplo, tente envolver esse <input />
em um <div>
:
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;
Isso quebrará o código porque agora, findDOMNode(this)
encontra o nó do DOM <div>
, mas o código espera um nó do DOM <input>
. Para evitar esse tipo de problema, use createRef
para gerenciar um nó do DOM específico.
Neste exemplo, findDOMNode
não é mais usado. Em vez disso, inputRef = createRef(null)
é definido como um campo de instância na classe. Para ler o nó do DOM a partir dele, você pode usar this.inputRef.current
. Para anexá-lo ao JSX, você renderiza <input ref={this.inputRef} />
. Isso conecta o código usando o nó do DOM ao seu JSX:
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;
Em React moderno sem componentes de classe, o código equivalente chamaria useRef
em vez disso:
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" /> }
Leia mais sobre como manipular o DOM com refs.
Lendo o nó do DOM de um componente filho a partir de um ref encaminhado
Neste exemplo, findDOMNode(this)
encontra um nó do DOM que pertence a outro componente. O AutoselectingInput
renderiza MyInput
, que é seu próprio componente que renderiza um <input>
do navegador.
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;
Observe que chamar findDOMNode(this)
dentro de AutoselectingInput
ainda fornece o DOM <input>
—mesmo que o JSX para esse <input>
esteja oculto dentro do componente MyInput
. Isso parece conveniente para o exemplo acima, mas leva a um código frágil. Imagine que você quisesse editar MyInput
mais tarde e adicionar um <div>
de encapsulamento ao redor dele. Isso quebraria o código de AutoselectingInput
(que espera encontrar um <input>
).
Para substituir findDOMNode
neste exemplo, os dois componentes precisam se coordenar:
AutoSelectingInput
deve declarar um ref, como no exemplo anterior, e passá-lo para<MyInput>
.MyInput
deve ser declarado comforwardRef
para aceitar esse ref e encaminhá-lo para o nó<input>
.
Esta versão faz isso, então não precisa mais de findDOMNode
:
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;
Aqui está como esse código pareceria com componentes de função em vez de classes:
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" /> }
Adicionando um elemento <div>
de encapsulamento
Às vezes, um componente precisa saber a posição e o tamanho de seus filhos. Isso torna tentador encontrar os filhos com findDOMNode(this)
, e então usar métodos do DOM como getBoundingClientRect
para medições.
Atualmente, não há equivalente direto para esse caso de uso, razão pela qual findDOMNode
está obsoleto, mas ainda não foi removido completamente do React. Enquanto isso, você pode tentar renderizar um nó <div>
de encapsulamento ao redor do conteúdo como uma solução alternativa e obter um ref para esse nó. No entanto, wrappers extras podem quebrar a estilização.
<div ref={someRef}>
{children}
</div>
Isso também se aplica ao foco e à rolagem para filhos arbitrários.