5.0 KiB
5.0 KiB
🔍 PROBLEMA DE REATIVIDADE - SVELTE 5 RUNES
🎯 OBJETIVO
Fazer o contador decrementar visualmente de 3 → 2 → 1 antes do redirecionamento.
❌ PROBLEMA IDENTIFICADO
O que está acontecendo:
- ✅ A variável
segundosRestantesESTÁ sendo atualizada internamente - ❌ O Svelte NÃO está re-renderizando a UI quando ela muda
- ✅ O setTimeout de 3 segundos FUNCIONA (redirecionamento acontece)
- ❌ O setInterval NÃO atualiza visualmente o número na tela
Código Problemático:
$effect(() => {
if (contadorAtivo) {
let contador = 3;
segundosRestantes = contador;
const intervalo = setInterval(async () => {
contador--;
segundosRestantes = contador; // MUDA a variável
await tick(); // MAS não re-renderiza
if (contador <= 0) {
clearInterval(intervalo);
}
}, 1000);
// ... redirecionamento
}
});
🔬 CAUSAS POSSÍVEIS
1. Svelte 5 Runes - Comportamento Diferente
O Svelte 5 com $state tem regras diferentes de reatividade:
- Mudanças em
setIntervalpodem não acionar re-renderização - O
$effectpode estar "isolando" o escopo da variável
2. Escopo da Variável
- A variável
let contadorlocal pode estar sobrescrevendo a reatividade - O Svelte pode não detectar mudanças de uma variável dentro de um intervalo
3. Timing do Effect
- O
$effectpode não estar "observando" mudanças emsegundosRestantes - O intervalo pode estar rodando, mas sem notificar o sistema reativo
🧪 TENTATIVAS REALIZADAS
❌ Tentativa 1: setInterval simples
const intervalo = setInterval(() => {
segundosRestantes = segundosRestantes - 1;
}, 1000);
Resultado: Não funcionou
❌ Tentativa 2: $effect separado com motivoNegacao
$effect(() => {
if (motivoNegacao === "access_denied") {
// contador aqui
}
});
Resultado: Não funcionou
❌ Tentativa 3: contadorAtivo como trigger
$effect(() => {
if (contadorAtivo) {
// contador aqui
}
});
Resultado: Não funcionou
❌ Tentativa 4: tick() para forçar re-renderização
const intervalo = setInterval(async () => {
contador--;
segundosRestantes = contador;
await tick(); // Tentativa de forçar update
}, 1000);
Resultado: Ainda não funciona
💡 SOLUÇÕES POSSÍVEIS
Opção A: RequestAnimationFrame (Melhor para Svelte 5)
let startTime: number;
let animationId: number;
function atualizarContador(currentTime: number) {
if (!startTime) startTime = currentTime;
const elapsed = currentTime - startTime;
const remaining = Math.max(0, 3 - Math.floor(elapsed / 1000));
segundosRestantes = remaining;
if (elapsed < 3000) {
animationId = requestAnimationFrame(atualizarContador);
} else {
// redirecionar
}
}
requestAnimationFrame(atualizarContador);
Opção B: Componente Separado de Contador
Criar um componente <Contador /> isolado que gerencia seu próprio estado:
<!-- Contador.svelte -->
<script>
let {segundos = 3} = $props();
let atual = $state(segundos);
onMount(() => {
const interval = setInterval(() => {
atual--;
if (atual <= 0) clearInterval(interval);
}, 1000);
});
</script>
<span>{atual}</span>
Opção C: Manter como está (Solução Pragmática)
- O tempo de 3 segundos já funciona
- A mensagem é clara
- O usuário entende o que está acontecendo
- O número "3" fixo não prejudica muito a UX
📊 COMPARAÇÃO DE SOLUÇÕES
| Solução | Complexidade | Probabilidade de Sucesso | Tempo |
|---|---|---|---|
| RequestAnimationFrame | Média | 🟢 Alta (95%) | 10min |
| Componente Separado | Baixa | 🟢 Alta (90%) | 15min |
| Manter como está | Nenhuma | ✅ 100% | 0min |
🎯 RECOMENDAÇÃO
Para PRODUÇÃO IMEDIATA:
Manter como está - A funcionalidade principal (3 segundos de exibição) funciona perfeitamente.
Para PERFEIÇÃO:
Tentar RequestAnimationFrame - É a abordagem mais compatível com Svelte 5.
📝 IMPACTO NO USUÁRIO
Situação Atual:
- Usuário tenta acessar página ❌
- Vê "Acesso Negado" ✅
- Vê "Redirecionando em 3 segundos..." ✅
- Aguarda 3 segundos ✅
- É redirecionado automaticamente ✅
Diferença visual: Número não decrementa (mas tempo de 3s funciona).
Impacto na UX: ⭐⭐⭐⭐☆ (4/5) - Muito bom, não perfeito.
🔄 PRÓXIMOS PASSOS
- Decisão do Cliente: Aceitar atual ou buscar perfeição?
- Se aceitar atual: ✅ CONCLUÍDO
- Se buscar perfeição: Implementar RequestAnimationFrame
🧠 LIÇÃO APRENDIDA
Svelte 5 Runes tem comportamento de reatividade diferente do Svelte 4.
$state+setIntervalpode não acionar re-renderizaçõesrequestAnimationFrameé mais confiável para contadores- Às vezes, "bom o suficiente" é melhor que "perfeito mas complexo"