DEV Community

Taise Soares
Taise Soares

Posted on • Updated on

Série React Hooks: useImperativeHandle

React hook

Olá pessoas, vamos iniciar uma séria somente com os hooks existentes no ReactJs. Nesse primeiro capitulo vamos falar do hook useImperativeHandle. bora la?

Caso queriam ver os outros artigos sobre essa série, segue links de artigos anteriores:

useImperativeHandle

No React, componentes são os blocos de construção de uma aplicação. Eles são peças de código reutilizáveis que encapsulam um conjunto de funcionalidades e podem ser compostos juntos para formar uma aplicação. Porém, muitas vezes, precisamos interagir com um componente de fora de seu componente pai. É aí que o useImperativeHandle entra em jogo.

Esse hook é utilizado para expor uma instância de um componente filho para um componente pai, permitindo que o pai possa chamar métodos ou acessar propriedades da instância do filho diretamente. Essa é uma maneira de expor uma determinada parte da API de um componente para seu componente pai. Para usar o useImperativeHandle, você precisa primeiro criar uma referência ao componente filho usando o hook useRef(Calma! esse fica para um próximo artigo, prometo).

Bora para o primeiro exemplo

saca só pessoal, imagine que você está desenvolvendo um componente que representa um cronômetro, e esse componente tem um botão de "start". Quando o botão é clicado, o cronômetro deve começar a contar.

Para implementar essa funcionalidade, você precisa acessar diretamente a instância do componente que representa o cronômetro, para poder chamar o método start() a partir do componente pai. É aí que entra o useImperativeHandle!

O hook useImperativeHandle é utilizado para definir quais métodos e propriedades devem ser expostos para o componente pai através da referência. Vamos ver um exemplo:

import { forwardRef, useImperativeHandle } from 'react';

export default const Stopwatch = forwardRef((props, ref) => {
  const [seconds, setSeconds] = useState(0);
  const [paused, setPaused] = useState(true);

  const start = () => {
    setPaused(false);
  };

  useInterval(() => {
    if (!paused) {
      setSeconds(seconds + 1);
    }
  }, 1000);

  useImperativeHandle(ref, () => ({
    start,
    seconds,
  }));

  return (
    <div>
      <p>{seconds} seconds</p>
      <button onClick={start}>Start</button>
    </div>
  );
});
Enter fullscreen mode Exit fullscreen mode

Nesse exemplo, o componente Stopwatch utiliza o hook useImperativeHandle para expor os métodos start() e seconds para o componente pai. O método start() inicia o cronômetro e a propriedade seconds representa a quantidade de segundos que o cronômetro está contando.

No componente pai, podemos utilizar a referência passada para o componente Stopwatch para chamar o método start() e acessar a propriedade seconds diretamente, da seguinte maneira:

import { useRef } from 'react';
import Stopwatch from './Stopwatch';

const App = () => {
  const stopwatchRef = useRef();

  const handleStart = () => {
    stopwatchRef.current.start();
  };

  return (
    <div>
      <Stopwatch ref={stopwatchRef} />
      <button onClick={handleStart}>Iniciar cronômetro</button>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Perceba agora que o componente pai possui uma referência para o componente Stopwatch, que pode ser passada como propriedade para o componente filho. Quando o botão é clicado, o método start() é chamado a partir da referência do componente Stopwatch.

Ainda confuso, vamos para um outro exemplo

Imagine que tenhamos um componente filho chamado TextInput e queremos acessar seu método focus() de seu componente pai, algo da seguinte maneira:

import { useRef, useImperativeHandle, forwardRef } from 'react';

const TextInput = forwardRef((props, ref) => {
  const inputRef = useRef(null);

  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));

  return (
    <input type="text" ref={inputRef} />
  );
});

export default TextInput;
Enter fullscreen mode Exit fullscreen mode

Legal, o que fizemos acima foi criar um componente TextInput que recebe uma referência como prop. Depois o que fazemos é usar o useRef para criar uma referência ao elemento input e, então, usamos o useImperativeHandle para expor o método focus() do elemento input para seu componente pai.

Note que o useImperativeHandle recebe dois argumentos, sendo:

  • O primeiro argumento é a referência que queremos expor
  • Já o segundo argumento é uma função que retorna um objeto contendo os métodos que queremos expor.

Com isso, queremos expor o método focus() do elemento input, então criamos um objeto com um método focus() que chama o método focus() do elemento input. (focus que chama focus, ficou confuso né? Calma meu pequeno gafanhoto, já vai ficar claro).

Bora, agora que criamos o componente TextInput com o hook useImperativeHandle, podemos usá-lo em seu componente pai e chamar seu método focus() diretamente da seguinte maneira:

import { useRef } from 'react';
import TextInput from './TextInput';

function App() {
  const textInputRef = useRef(null);

  const handleClick = () => {
    textInputRef.current.focus();
  };

  return (
    <div>
      <button onClick={handleClick}>Focus Input</button>
      <TextInput ref={textInputRef} />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Agora note, que criamos um componente pai chamado App que renderiza um botão e o componente TextInput. Então criamos uma referência ao componente TextInput usando o useRef e, em seguida, o passamos como uma prop para o componente TextInput.

Com isso, quando o botão é clicado, chamamos o método focus()do componente TextInput diretamente por meio de sua referência.

Partiu resumo

Resumindo o hook useImperativeHandle é utilizado para definir quais métodos e propriedades devem ser expostos para o componente pai através da referência.

Ele permite aos desenvolvedores expor métodos específicos de um componente filho para seu componente pai. É particularmente útil quando precisamos interagir com um componente filho de fora de seu componente pai. Usando o useRef para criar uma referência ao componente filho e o useImperativeHandle para expor seus métodos, podemos acessar e chamar esses métodos diretamente em seu componente pai.

Isso é tudo pessoal, espero que esse primeiro artigo de uma série sobre os hooks do ReactJS tenha exclarecido qualquer dúvida.

Até a próxima da série.

Top comments (0)

The discussion has been locked. New comments can't be added.