remember — conceitos-chave, preservação de valores entre recomposições

Autor: IT Sectr Publicado: 2026-06-28 Tempo de leitura: 8 min

remember é uma função no Jetpack Compose que permite preservar um valor entre recomposições, evitando a redefinição de estado em cada reinicialização de uma função Composable. Sem remember, todas as variáveis declaradas dentro de uma função seriam redefinidas em cada atualização de UI, tornando o estado instável e inútil. De acordo com Google Android Developers, 2026, o uso correto de remember é a base do gerenciamento adequado de estado em UI declarativa.

Pontos Principais

  • remember preserva um valor no slot de composição entre recomposições da função
  • Chaves em remember(key) determinam quando o valor deve ser recalculado
  • rememberSaveable preserva o valor na rotação da tela e minimização do aplicativo
  • derivedStateOf cria estado derivado, otimizando cálculos durante a recomposição
  • Redefinição de remember ocorre apenas quando a função sai da composição

O que é remember no Jetpack Compose

remember é uma função integrada do Jetpack Compose do pacote androidx.compose.runtime que cria um objeto preservando seu valor entre chamadas sucessivas de uma função Composable. Tecnicamente, remember trabalha com slots — células especiais de memória alocadas para cada posição de chamada de função na árvore de UI. Enquanto a função permanecer na composição (não removida por uma condição if), remember retornará o valor salvo em cada recomposição.

A sintaxe de remember é simples: dentro de chaves, especifica-se o bloco de cálculo do valor inicial. O bloco é executado apenas uma vez — durante a primeira composição da função. Todas as recomposições subsequentes retornam o valor já salvo sem reexecutar o bloco. No entanto, se um parâmetro chave for especificado, o bloco é reexecutado quando a chave muda, permitindo recalcular o valor com base nos dados de entrada.

remember não é mágica do Kotlin — é uma função simples com um parâmetro chave e uma lambda de cálculo. Sua implementação interna usa Composer para ler e escrever nos slots. O compilador Kotlin, ao ver uma chamada remember, gera código que acessa o CompositionContext atual e gerencia os slots. Isso significa que remember só pode ser chamado dentro de uma função Composable ou outra função no contexto de composição.

Tipos de remember: remember, rememberSaveable, derivedStateOf

No Jetpack Compose, existem três variantes principais de remember, cada uma com seu propósito. O remember básico preserva o valor apenas na memória do processo atual — na rotação da tela (config change), o Compose recria a Composition e todos os valores de remember são redefinidos. Para preservar dados durante mudanças de configuração e parada do processo, usa-se rememberSaveable.

rememberSaveable serializa o valor em um Bundle através do mecanismo SavedStateHandle ou Parcelable. Isso permite sobreviver à rotação da tela, à configuração "Não manter atividades" e até mesmo à minimização temporária do aplicativo. No entanto, rememberSaveable impõe restrições ao tipo de dados que pode armazenar: eles devem ser primitivos, Parcelable, Serializable ou suportar um conversor Saver.

derivedStateOf não é um mecanismo de preservação, mas uma otimização. Cria um State cujo valor é calculado a partir de outros objetos State. derivedStateOf reage a mudanças nos estados fonte, mas recalcula o valor apenas quando há assinantes. Se a recomposição atual não lê o derivedStateOf, o cálculo não é realizado, economizando recursos em atualizações frequentes mas desnecessárias.

kotlin
@Composable
fun RememberVariants() {
    // 1. Remember básico: persiste até sair da composição
    val createdAt = remember { System.currentTimeMillis() }

    // 2. rememberSaveable: sobrevive à rotação da tela
    var username by rememberSaveable { mutableStateOf("") }

    // 3. derivedStateOf: calculado apenas quando necessário
    val isButtonVisible = remember {
        derivedStateOf { username.length() > 3 }
    }

    Text("Criado: $createdAt")
    TextField(value = username, onValueChange = { username = it })

    if (isButtonVisible.value) {
        Text("O botão será mostrado")
    }
}

remember vs rememberSaveable: quando usar cada um

A escolha entre remember e rememberSaveable depende de quão crítico é preservar os dados durante mudanças de configuração. Para estados temporários que não são importantes perder na rotação (animação, posição atual de rolagem, estado de foco) — remember comum é suficiente. Para dados críticos (texto em formulários, itens selecionados, caixas de seleção) — use rememberSaveable.

Desempenho: rememberSaveable é mais lento que remember comum porque requer serialização em um Bundle. Use rememberSaveable apenas para dados que realmente precisam sobreviver à recriação da Activity. Para todo o resto — remember simples. O uso excessivo de rememberSaveable causa lentidão na rotação da tela e ao alternar entre aplicativos.

Se você trabalha com classes que não suportam Parcelable ou Serializable, use Saver — um conversor que define como salvar e restaurar o objeto. Saver é descrito por um par de lambdas: save (converte o objeto para um tipo armazenável) e restore (restaura o objeto a partir dos dados salvos). Um Saver padrão já está implementado para mutableStateListOf e mutableStateMapOf.

CaracterísticarememberrememberSaveable
Preservação durante recomposiçãoSimSim
Preservação na rotaçãoNãoSim
Preservação na parada do processoNãoSim
Requisitos de tipoQualquerParcelable, Serializable, Saver
DesempenhoAltoMédio

Exemplos de uso de remember em projetos reais

Considere um cenário típico — uma tela de edição de perfil onde remember é usado para vários propósitos: armazenar estado dos campos do formulário, calcular valores derivados e armazenar em cache operações computacionalmente caras.

kotlin
data class ProfileUiState(
    val name: String = "",
    val bio: String = "",
    val isSaving: Boolean = false
)

@Composable
fun ProfileEditor() {
    var state by rememberSaveable { mutableStateOf(ProfileUiState()) }
    val isValid = remember {
        derivedStateOf { state.name.isNotBlank() && state.bio.length() <= 500 }
    }

    val bioWarning = remember(state.bio) {
        if (state.bio.length() > 400) {
            "${500 - state.bio.length} chars left"
        } else null
    }

    Column(modifier = Modifier.padding(16.dp)) {
        OutlinedTextField(
            value = state.name,
            onValueChange = { state = state.copy(name = it) },
            label = { Text("Nome") }
        )

        OutlinedTextField(
            value = state.bio,
            onValueChange = { state = state.copy(bio = it) },
            label = { Text("Sobre") }
        )

        bioWarning?.let { Text(it, color = MaterialTheme.colorScheme.error) }

        Button(onClick = { /* save */ },
            enabled = isValid.value) {
            Text("Salvar")
        }
    }
}

No exemplo, o estado é salvo via rememberSaveable — o texto não será perdido na rotação da tela. isValid é calculado via derivedStateOf, o que evita cálculos desnecessários durante as recomposições. bioWarning usa remember com a chave bio — este é um cálculo caro (opcional, para demonstração) que recalcula apenas quando bio muda, não em cada recomposição.

Estados derivados e remember com chaves

Estados derivados são valores calculados a partir de outros objetos State. Em vez de calculá-los em cada recomposição e desperdiçar CPU em resultados idênticos, remember com derivedStateOf calcula o valor apenas quando as fontes mudam. Isso é especialmente útil para filtragem, ordenação e agregação de dados.

remember com chaves (remember(key) { calculation }) é outro mecanismo de otimização. Se a chave não mudou desde a última recomposição, o bloco de cálculo não é executado e o valor em cache é retornado. Isso é conveniente para armazenar em cache objetos cuja criação é cara: formatação de datas, análise JSON, criação de grandes coleções imutáveis.

kotlin
@Composable
fun SearchResults(allItems: List<Item>, query: String) {
    // derivedStateOf: filtro recalculado apenas quando as entradas mudam
    val filtered = remember {
        derivedStateOf {
            allItems.filter { it.title.contains(query, true) }
        }
    }

    // remember com chave: estatísticas formatadas recalculadas apenas na mudança da consulta
    val statsText = remember(query) {
        "Results for query \"$query\": ${filtered.value.size}"
    }

    Text(statsText)
    LazyColumn {
        items(filtered.value, key = { it.id }) { item ->
            Text(item.title)
        }
    }
}

filtered é um derivedStateOf que recalcula automaticamente quando allItems ou query mudam. statsText usa remember(query) — a formatação cara de strings é realizada apenas quando a consulta de pesquisa muda. A combinação de derivedStateOf e remember com chaves proporciona o máximo desempenho: o estado derivado é calculado apenas quando necessário e objetos complexos são armazenados em cache até a chave mudar.

Perguntas Frequentes

Pode-se usar remember fora de uma função Composable?

Não, remember é uma função do pacote compose.runtime que requer um CompositionContext. Só pode ser chamada dentro de uma função @Composable ou dentro de outra função chamada de uma Composable. Para armazenar dados fora da composição, use ViewModel.

O que acontece se não especificar uma chave em remember?

Sem uma chave, remember executa o bloco de cálculo apenas uma vez — durante a primeira composição. Todas as recomposições subsequentes retornam o valor salvo. Se precisar recalcular o valor quando os dados mudam, certifique-se de especificá-los como chave: remember(data) { compute(data) }.

Como forçar a redefinição de remember?

Não há uma maneira direta de redefinir remember. A única maneira é remover a função da composição (por exemplo, escondendo-a com uma condição if) e depois mostrá-la novamente. Ao reentrar, o bloco remember é executado novamente, criando um novo valor inicial.

Como remember difere de ViewModel?

remember armazena estado em um slot de função Composable e vive enquanto a função estiver em composição. ViewModel vive enquanto durar o ciclo de vida da tela. ViewModel é preservado na rotação e usado para lógica de negócio. remember é para estado local de UI que não é necessário fora de uma única função.

Remember funciona em componentes Preview?

Sim, remember funciona corretamente em funções @Preview Composable porque Preview cria um CompositionContext completo. No entanto, rememberSaveable pode não funcionar corretamente no Preview porque SavedStateHandle pode estar ausente no ambiente de prévia.

Resumo

  • remember preserva um valor no slot de composição e sobrevive às recomposições da função
  • rememberSaveable adicionalmente preserva o valor na rotação da tela e parada do processo
  • derivedStateOf cria estado derivado com cálculos preguiçosos
  • As chaves em remember(key) controlam o recálculo do valor em cache
  • Redefinição de remember ocorre apenas quando a função é removida da composição
  • Desempenho: derivedStateOf e chaves previnem cálculos desnecessários durante a recomposição
  • Recomendação: use rememberSaveable para campos de entrada e remember + derivedStateOf para valores calculados

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também