Adicionando interatividade em uma página

Version: 1.0.0

Uma das razões pelas quais o Deco é rápido é a nossa abordagem centrada no servidor para criar sites. Isso significa que todo o código que você escreve é executado em nossos servidores, em vez de ser executado em dispositivos de usuário lentos e inconsistentes (navegador). No entanto, às vezes precisamos fornecer interatividade extra aos nossos sites, como adicionar manipuladores de eventos onClick, useState ou useEffect. Neste guia, você aprenderá como criar componentes que são executados no navegador. Certifique-se de ler nossas dicas de desempenho antes de criar qualquer JavaScript no navegador, para evitar problemas comuns com o JavaScript do lado do cliente.

Sumário

  1. Tornando os componentes interativos
  2. Limitações de uso das islands
  3. Compartilhando estado entre as islands
  4. Considerações e dicas

Tornando os componentes interativos

Suponha que você tenha o seguinte componente. Um contador que permite ao usuário adicionar/subtrair o valor exibido.

Este componente pode ser implementado com o seguinte código:

import { useState } from "preact/hooks";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <button onClick={() => setCount(count - 1)}>
        -
      </button>
      <span>{count}</span>
      <button onClick={() => setCount(count + 1)}>
        +
      </button>
    </div>
  );
}

Ao criar um arquivo chamado Counter.tsx e colocá-lo na pasta islands, obtemos o seguinte resultado na tela:

Jul-13-2023 10-38-29

Agora isso é chamado de island!

Embora adicionar islands ao seu projeto pareça tentador, tenha em mente que as islands tornam os sites mais lentos e prejudicam a métrica TBT (Total Blocking Time). Portanto, antes de mover qualquer componente para a pasta island, verifique se sua interatividade final:

  • Não é alcançada por meio de navegação de página com links ou envio de formulários...
  • Não é uma interação construída puramente com CSS...
  • Requer manipulação de elementos ou estado da página atual (por exemplo, usando onClick, onChange, useEffect, outro hook ou um ouvinte de eventos)

Limitações de uso das islands

As islands são componentes do Preact. Isso significa que elas aceitam props. No entanto, esses valores devem ser um dos seguintes:

  • Tipos primitivos string, boolean, bigint e null
  • Objetos simples com chaves string e valores serializáveis
  • Arrays de valores serializáveis
  • Uint8Array
  • Elementos JSX (SOMENTE como props.children)
  • Sinais do Preact (se o valor do sinal for serializável)
  • A maioria dos números (Infinity, -Infinity e NaN são convertidos para null)

Objetos complexos como Date, funções e classes personalizadas não são aceitos como props de islands.

Utilizando signals no lugar de state

O useState exige que se trabalhe com uma função a parte para a atualização de valor. Preact, e outros sistemas, oferecem Signals para tratamento de estado até do useState. Um signal tem uma referência que tem valor mas que também tem um atributo .value que permite atualizar esse valor.

Dentro de um componente, caso o estado seja só usado localmente, é possível fazer uso do hook useSignal para criar esses elementos que podem ser utilizado no corpo da função ou no próprio JSX retornado, como no exemplo abaixo.

import { useSignal } from "@preact/signals";

export default function Counter() {
  const count = useSignal(0);

  return (
    <div>
      <button onClick={() => count.value--}>
        -
      </button>
      <span>{count}</span>
      <button onClick={() => count.value++}>
        +
      </button>
    </div>
  );
}

Compartilhando estado entre as islands

No desenvolvimento normal do Preact, o compartilhamento de estado entre componentes geralmente é feito por meio da API Context. Isso funciona bem para um aplicativo de lado do cliente completo. No entanto, como estamos usando a arquitetura de islands, compartilhar estado entre as islands requer uma nova abordagem.

Os signals são uma ótima maneira de compartilhar estado entre as islands, pois é possível publicar e se inscrever em eventos de alteração em uma API concisa.

Para usar signals, importe:

import { signal } from "@preact/signals";

Agora, use o escopo global para criar, modificar e se inscrever em um signal:

import { signal } from "@preact/signals";

const count = signal(0);

// Leia o valor de um signal acessando .value:
console.log(count.value); // 0

// Atualize o valor de um signal:
count.value += 1;

// O valor do signal foi alterado:
console.log(count.value); // 1

Para definir efeitos colaterais em mudanças de signal, use as operações effect, batch, computed ou useComputed. Consulte a documentação dos signals para obter mais detalhes. Além disso, dê uma olhada em compartilhando estado entre islands.

Observe que o compartilhamento de estado por meio da API Context NÃO funcionará, pois o contexto estará fora das islands e, portanto, só estará disponível no servidor.

Considerações e dicas

Ao transformar um componente em uma island, pelo menos o tamanho dele em bytes será duplicado. O servidor renderiza o HTML para esse elemento e o envia para o navegador, mas também envia basicamente o mesmo HTML mais o JS a ser injetado no lado do cliente. Portanto, tente criar apenas as islands necessárias, pois elas tornam o processo de renderização mais intensivo em

Leitura complementar:

Was this page helpful?
Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum
Continue reading