O Problema da Sincronização
O botão RSVP funciona de uma forma limitada: ele muda de texto quando clicado. Vamos expandir um pouco. Cada card agora mostra um contador de confirmações, e clicar no botão incrementa esse contador:
for (const ev of events) {
// ... (criar título, data, descrição, local como antes)
let rsvpCount = 0;
const counter = document.createElement("p");
counter.textContent = `Confirmações: ${rsvpCount}`;
const btn = document.createElement("button");
btn.textContent = "RSVP";
btn.addEventListener("click", () => {
rsvpCount++;
counter.textContent = `Confirmações: ${rsvpCount}`;
});
card.append(title, date, desc, location, info, counter, btn);
container.appendChild(card);
}
Código 6-8: Botão RSVP que incrementa um contador local de confirmações.
Funciona. Clique no botão, o número sobe. Mas agora imagine que a página também mostra um resumo no topo — o total de confirmações de todos os eventos:
const summary = document.createElement("p");
summary.textContent = "Total de confirmações: 0";
document.body.insertBefore(summary, container);
Quando o usuário clica num botão RSVP, o contador daquele card atualiza. Mas o resumo no topo continua mostrando 0. Para atualizá-lo, precisamos encontrar o elemento do resumo e recalcular o total:
btn.addEventListener("click", () => {
rsvpCount++;
counter.textContent = `Confirmações: ${rsvpCount}`;
// Atualizar o resumo no topo
totalCount++;
summary.textContent = `Total de confirmações: ${totalCount}`;
});
Dois lugares exibindo o mesmo dado, duas linhas de código para atualizar. Agora adicione um terceiro: um badge no título da página mostrando o total.
btn.addEventListener("click", () => {
rsvpCount++;
counter.textContent = `Confirmações: ${rsvpCount}`;
totalCount++;
summary.textContent = `Total de confirmações: ${totalCount}`;
// Atualizar o badge no título
pageTitle.textContent = `TamoJunto — Eventos (${totalCount})`;
});
Três lugares, três linhas. E se esquecermos um? O dado fica inconsistente — o card mostra 3, o resumo mostra 2, o título mostra 1. O usuário vê números diferentes para a mesma informação. E cada novo lugar que exibir esse dado é mais uma linha que alguém precisa lembrar de adicionar1.
O problema não é que o código está errado. Cada linha individualmente faz o que deve. O problema é que o desenvolvedor está fazendo um trabalho que deveria ser automático: toda vez que um dado muda, todo lugar que exibe esse dado precisa ser atualizado manualmente. A manipulação direta do DOM não oferece nenhum mecanismo para isso.
Essa é a sincronização de estado — o dado (state) e a interface (view) precisam estar em sincronia, e com manipulação direta do DOM, manter essa sincronia é responsabilidade inteiramente do programador.
-
O contador de RSVP aqui é puramente local — ele existe apenas no JavaScript da página. Nenhuma requisição é enviada ao backend, e recarregar a página zera tudo. Endpoints de escrita (como
POST /api/rsvps) só aparecem quando o TamoJunto precisar persistir essas confirmações. ↩