Modal funcional com React Hooks

João Victor Oliveira
React Brasil
4 min readOct 24, 2019

--

Meu objetivo é mostrar um pouco do comportamento de um componente funcional React.

Iremos criar um componente de modal apenas usando React hooks. Nosso modal deverá ter o seguinte comportamento:

HOOKS

Juntamente com componentes funcionais precisamos utilizar os hooks. Essa feature é que vai permitir nossos componentes de função ter as mesmas características de um componente de classe: utilizar estado, executar ação ao montar um componente, entre outras coisas mais.

O uso de componentes funcionais surgiu em 2018 para substituir os componentes de classe. São mais simples de escrever (menos verbosos) e ainda mais performáticos.

Recomendo buscar mais detalhes dos hooks. Não falarei muito sobre isso pois não é o objetivo aqui.

Abaixo link para API de referência Hook:

Vamos para o código!

Começaremos usando o comando

npx create-react-app modal-react

em uma pasta a sua escolha (modal-react será o nome da aplicação). Esse comando pode levar algum tempinho e irá construir uma aplicação básica com uso do React.

Criando o Componente

O comando irá gerar um App.js. Vamos refatorar para o ECMAScript 6:

O componente Modal mostrado acima corresponde ao nosso modal, crie a pasta src/Component/Modal e lá crie o arquivo Modal.jsx:

O props serve para recuperar os parâmetros que o componente pode receber ao ser declarado.

Também adicione na mesma pasta o arquivo Modal.css:

useState

O useState retorna uma variável e uma função assíncrona que serve para alterar o valor dessa variável. Nosso parâmetro indica o valor inicial dessa variável.

O setDropdown após receber um novo valor o coloca na fila de re-renderização do componente.

Repare que colocamos a função de showDropdown no click do botão e adicionamos um evento ao body. Quando clicarmos no botão, o modal deve aparecer, mas quando clicarmos em qualquer outro canto (no body) ele deve sumir. A variável dropdown (que estamos alterando o valor) é passada via props para o Modal e isso adicionará comportamento css ao nosso componente.

Adicione o seguinte trecho ao App.css para o comportamento explicado acima funcionar:

Até aqui temos dois problemas: quando clicamos dentro do modal ele irá desaparecer e quando clicamos no botão pela segunda vez o Modal não irá sair da tela…Não é isso que queremos, cuidaremos disso mais adiante.

Propagação de evento

Como podemos evitar que o modal desapareça e apareça logo em seguida quando o botão é clicado?

O que acontece aí é causado pelo efeito de capturing (que podemos ver na imagem). O evento do click começa lá na raíz e se propaga até chegar no botão. Ou seja, executa nossas duas funções sempre que o botão é clicado, já que o body é ancestral do botão.

A função .stopPropagation() vai impedir que o click chegue até a ação do botão, parando no body (como mostrarei o código a seguir juntamente com o useRef).

Para mais detalhes recomendo o link abaixo:

useRef

Esse outro hook nos retorna um objeto no qual podemos inicializar passando parâmetro. Teremos acesso a esse objeto pela propriedade .current. O objeto retornado aqui persistirá durante todo ciclo de vida do componente.

Atente-se a props modalRef que é passada no componente Modal. É a referência dele que vamos pegar com .current e então podemos verificar se o evento de click contém ou não o nosso Modal.

Chegando até aqui o seu modal já deve estar funcionando perfeitamente! :)

Código completo

O código apresentado está em repositório público no meu Github:

--

--