DEV Community

Cover image for Teleport do Vue.js 3 vs Portals do ReactJS: uma análise comparativa para lidar com elementos fora do contexto do componente pai.
Jonathan Santos da Silva
Jonathan Santos da Silva

Posted on

Teleport do Vue.js 3 vs Portals do ReactJS: uma análise comparativa para lidar com elementos fora do contexto do componente pai.

O Vue.js 3 é uma das mais populares bibliotecas de JavaScript para construção de interfaces de usuário, e sua recente atualização trouxe consigo um novo componente interessante, o Teleport. Neste post, vamos fazer uma introdução ao Teleport e também uma comparação com os Portals do ReactJS.

Antes de começarmos, é importante entendermos que ambos os recursos foram criados para resolver um problema comum em aplicações web: como lidar com elementos que precisam ser exibidos fora do contexto do seu componente pai.

Em Vue, um componente é renderizado dentro de sua própria estrutura de componentes, o que significa que todas as suas propriedades e métodos são restritos a essa estrutura. No entanto, às vezes é necessário exibir um elemento em outro local da página, fora do contexto de seu componente pai. É nesse momento que podemos utilizar o Teleport.

O Teleport permite que nosso componente seja "teletransportado" como filho de outro elemento e em qualquer outro lugar da página, sem termos que nos preocupar com renderização e interação, mantendo os dados e informações do componente mesmo após ser mudado de lugar.

Para podermos utilizar do componente Teleport, só precisamos envolver o elemento a ser teleportado em uma tag <teleport> </teleport> e especificarmos o local que o elemento deve ser renderizado, como no exemplo a baixo:


Modal.vue

<template>
    <teleport to="#modal-target">
      <div v-if="show" class="modal__body">
        <h1>Modal Title</h1>
        <p>Modal Content</p>
      </div>
    </teleport>
</template>

<script lang="ts">
export default {
  props: {
    show: {
      type: Boolean,
      required: true,
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

App.vue

<template>
  <div id="modal-target" class="modal__target"></div>
  <button @click="show = !show">Toggle Modal</button>
  <Modal :show="show" />
</template>
<script lang="ts">
import Modal from './components/Modal.vue';
export default {
  data() {
    return {
      show: false,
    };
  },
  components: {
    Modal,
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

Com o código acima, você pode ver que o elemento modal é renderizado como filho, no local especificado pela propriedade "to" que funciona da mesma forma que um seletor CSS. Com isso podemos alterar o local de renderização do nosso componente de modal, independente da sua posição na estrutura de elementos. Obtendo o seguinte resultado:


Resultado da abordagem utilizando componente  raw `Teleport` endraw  do vue3

O Teleport também possui uma propriedade para desabilita-lo em algum caso, podemos passar, por exemplo, para que ele seja desabilitado caso estejamos utilizando um dispositivo mobile apenas criando uma validação de tamanho de tela:


computed: {
    isMobile() {
      return screen.width <= 760;
    },
  },
Enter fullscreen mode Exit fullscreen mode

E adicionando isso na propriedade "disabled" do nosso componente Teleport:

    <teleport :disabled="isMobile" to="#modal-target">
      <div v-if="show" class="modal__body" style="">
        <h1>Modal Title</h1>
        <p>Modal Content</p>
      </div>
    </teleport>
Enter fullscreen mode Exit fullscreen mode

Resultado da abordagem utilizando componente  raw `Teleport` endraw  do vue3 porém com propriedade disbled


Um comparativo com portals do ReactJS

Agora vamos comparar o Teleport com os Portals do ReactJS. Em React, os Portais são usados para exibir elementos fora do contexto de seu componente pai. A ideia é semelhante ao Teleport, mas a implementação é um pouco diferente.

Em React, você precisa criar um componente Portal e usá-lo como um componente comum em sua aplicação. Aqui está um exemplo de código:

App.jsx

import React, { useState } from 'react';
import { createPortal } from 'react-dom';
import './App.css';

function Modal() {
  return createPortal(
    <div>
      <h1>Modal Title</h1>
      <p>Modal Content</p>
    </div>,
    document.getElementById('modal-root')
  );
}

function App() {
  const [show, setShow] = useState(false);
  return (
    <div>
      <button onClick={() => setShow(!show)}>Toggle Modal</button>
      {show && <Modal />}
      <div id="modal-root" class="modal__root"></div>
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

Assim como o Teleport, podemos obter um resultado parecido, nos permitindo renderizar o componente em qualquer local da página.

Resultado da abordagem utilizando componente  raw `Portals` endraw  do react

No entanto, a implementação é um pouco diferente, pois você precisa criar um componente específico e usá-lo como um componente comum.

Em resumo, o Teleport e os Portais são recursos semelhantes, criados para resolver o mesmo problema de exibir elementos fora do contexto de seu componente pai. O Teleport é uma adição interessante ao Vue.js 3 e é fácil de usar, enquanto os Portais são uma abordagem mais flexível, porém requerem uma implementação um pouco mais complexa.

A escolha entre o Teleport e os Portals depende da sua familiaridade com as ferramentas e do que você acha mais fácil de aprender. Se você já trabalha com Vue.js 3, o Teleport é uma opção fácil de implementar e pode ser mais adequado. Se você já está mais familiarizado com os Portals do ReactJS, pode ser mais fácil continuar usando essa abordagem. O importante é escolher a opção que você se sinta mais confortável em trabalhar e que seja mais fácil para você aprender.

Obrigado pela leitura!! Críticas construtivas e comentários são muito bem vindos 💚💙

Top comments (0)