State Managers no LWC Chegaram: Como o Summer ’26 Muda a Forma Como Você Compartilha Dados Entre Componentes
Você coloca um item de linha em uma oportunidade, e o card de resumo três componentes abaixo ainda mostra o total antigo. Então você escreve um evento customizado, dispara do editor, captura no pai, passa o novo valor como propriedade pública por dois componentes que nem precisam dele. Aí um quarto componente precisa do mesmo total, e você repete a corrente inteira.
Esse imposto existe no LWC desde o primeiro dia. O Summer ’26 finalmente entrega uma resposta que vem de fábrica.
State Managers atingiram disponibilidade geral nesta release, depois de uma temporada em developer preview e beta. O Salesforce Ben chamou de “a mudança mais significativa na arquitetura de dados do LWC em anos”, e a definição faz sentido assim que você vê o que ela elimina. Este artigo cobre o que é um state manager, a API exata que você escreve, como os componentes encontram o estado compartilhado, e os casos onde faz sentido usar isso no lugar das ferramentas que você já conhece.
O Problema Que State Managers Resolvem
Dois componentes na mesma página precisam dos mesmos dados. No LWC clássico, você tem três maneiras de fazer isso acontecer, e cada uma cobra um preço.
A primeira são propriedades públicas. Um pai possui os dados e passa para cada filho via campos @api. Quando os filhos estão dois ou três níveis abaixo, você passa a mesma propriedade por cada componente no meio do caminho, inclusive os que nunca leem aquele valor. Isso se chama prop drilling, e transforma uma refatoração simples em uma caça em cinco arquivos.
A segunda são eventos customizados. Um filho que altera o dado dispara um evento, o pai escuta, atualiza a própria cópia, e empurra o novo valor de volta para baixo. Dois componentes que leem e escrevem o mesmo valor produzem um loop de eventos subindo e propriedades descendo. A fiação funciona até você adicionar um terceiro componente, e aí a cadeia de eventos vira a peça mais frágil da sua página.
A terceira é o Lightning Message Service. O LMS transmite uma mensagem em um canal que qualquer assinante pode ouvir, o que é genuinamente útil quando os componentes estão em partes diferentes do DOM ou em regiões diferentes de uma página Lightning. Mas o LMS entrega uma mensagem, não um valor gerenciado. Você ainda possui o estado nas duas pontas, ainda trata a lógica de atualização duas vezes, e não há um único registro de qual é o valor atual.
Um state manager colapsa os três padrões em uma ideão só. Você coloca os dados e as funções que os alteram em um módulo próprio. Os componentes leem desse módulo e chamam suas funções. Ninguém passa props por um componente que não se importa com elas, e ninguém fia um evento só para manter duas cópias do mesmo número em sincronia.
O Que É um State Manager, Exatamente
Um state manager é um módulo JavaScript puro que guarda um conjunto relacionado de dados e as funções que os modificam. O guia oficial da Salesforce descreve três partes: uma função de definição que você passa para defineState, um conjunto de propriedades nomeadas que seguram o estado, e um conjunto de ações nomeadas que o modificam.
Você importa defineState da biblioteca @lwc/state e chama com um callback. Esse callback recebe algumas primitivas e retorna a forma do seu estado.
import { defineState } from '@lwc/state';
export default defineState(({ atom, computed, setAtom }) => {
const items = atom([]); // fonte da verdade
const count = computed([items], (list) => // valor derivado
list.value.length
);
const addItem = (item) => // ação
setAtom(items, [...items.value, item]);
return { items, count, addItem };
});Três primitivas carregam o peso aqui. Um atom envolve um único dado reativo e age como a fonte da verdade para aquele valor. Um computed deriva de um ou mais atoms e recalcula apenas quando esses atoms mudam — um total acumulado nunca sai de sincronia com a lista que ele soma. Uma ação (usando setAtom no exemplo acima) é o único jeito sancionado de alterar um atom. Componentes não alcançam e mutam o estado diretamente. Eles chamam uma ação, a ação muda o atom, e todo leitor atualiza.
Essa última regra é a vitória silenciosa. Como as ações são o único caminho de escrita, você sempre sabe onde um valor pode mudar. Quando o total parece errado, você tem uma função para inspecionar, não uma dispersão de handlers de evento por quatro componentes. O objeto que você retorna no final é a API pública. Qualquer coisa que você omita fica privada, o que dá controle real sobre o que cada componente que consome o estado pode ver ou fazer.
Como os Componentes Encontram o Estado Compartilhado
Definir um state manager é metade do trabalho. A outra metade é instanciar a mesma instância em todos os componentes que precisam dela. É aqui que o design mostra seu valor.
Um componente age como provider. Ele instancia o state manager na própria classe, e essa instância fica disponível para toda a árvore de componentes abaixo dele.
import { LightningElement } from 'lwc';
import cartState from 'c/cartStateManager';
export default class CartContainer extends LightningElement {
cart = cartState();
}Qualquer descendente lê a mesma instância com fromContext, importado de @lwc/state.
import { LightningElement } from 'lwc';
import { fromContext } from '@lwc/state';
import cartState from 'c/cartStateManager';
export default class CartSummary extends LightningElement {
cart = fromContext(cartState);
get total() {
return this.cart.value.total;
}
}O fromContext busca para cima na hierarquia de componentes, começando do próprio componente e subindo até a raiz, até encontrar a instância mais próxima daquele state manager. Isso se chama resolução por proximidade: um consumidor vê a instância do ancestral mais próximo e nenhuma outra.
Esse detalhe importa mais do que parece. Resolução por proximidade significa que você pode colocar duas instâncias independentes na mesma página. Imagine uma página mostrando duas oportunidades lado a lado. Envolva cada uma em seu próprio provider, e o summary dentro da oportunidade da esquerda resolve para o estado da esquerda, enquanto o summary da direita resolve para o da direita. Nenhum vaza para o outro. Você ganha estado com escopo sem inventar um esquema de nomes ou um canal por instância.
Reatividade, Sem Cerimônia
O modelo de atualização merece precisão, porque é ele que faz os getters acima funcionarem. Quando o valor de um atom muda, todo componente e todo valor computed que o observa atualiza automaticamente, e o framework re-renderiza os componentes afetados. Você não assina manualmente, e não chama um método de refresh. Você lê o estado em um getter ou numa expressão de template, e o sistema de reatividade rastreia a dependência para você.
Valores computed só recalculam quando suas próprias dependências mudam. Se o summary lê total e você muda um atom não relacionado no mesmo manager, o total não recalcula e o summary não re-renderiza sem motivo. Essa é uma diferença significativa em relação a um objeto compartilhado ingênuo onde qualquer mudança força todo mundo a reavaliar tudo.
O lado da escrita se mantém disciplinado de propósito. Leituras acontecem em qualquer lugar através das propriedades retornadas. Escritas acontecem apenas através de ações. Manter esses dois caminhos separados é o que permite você raciocinar sobre uma página com uma dúzia de componentes sem rastrear uma dúzia de listeners de evento.
Exemplo Prático: Carrinho de Compras
Vamos montar um exemplo completo para ver o state manager em ação.
1. O State Manager (cartStateManager.js)
import { defineState } from '@lwc/state';
export default defineState(({ atom, computed, setAtom }) => {
const items = atom([]);
const count = computed([items], (resolved) =>
resolved.items.value.length
);
const total = computed([items], (resolved) =>
resolved.items.value.reduce((sum, item) => sum + item.price * item.qty, 0)
);
const addItem = (item) => {
setAtom(items, [...items.value, item]);
};
const removeItem = (itemId) => {
setAtom(items, items.value.filter(i => i.id !== itemId));
};
const clearCart = () => {
setAtom(items, []);
};
return { items, count, total, addItem, removeItem, clearCart };
});2. O Provider (cartContainer.js)
import { LightningElement } from 'lwc';
import cartState from 'c/cartStateManager';
export default class CartContainer extends LightningElement {
cart = cartState();
get itemCount() {
return this.cart.value.count;
}
}3. O Componente Consumidor (cartItemList.js)
import { LightningElement } from 'lwc';
import { fromContext } from '@lwc/state';
import cartState from 'c/cartStateManager';
export default class CartItemList extends LightningElement {
cart = fromContext(cartState);
get items() {
return this.cart.value.items;
}
handleAddItem(event) {
this.cart.value.addItem({
id: event.detail.id,
name: event.detail.name,
price: event.detail.price,
qty: 1
});
}
handleRemoveItem(event) {
this.cart.value.removeItem(event.detail);
}
}Note que cartItemList nunca disparou um evento para avisar ninguém sobre a mudança. Ele chamou addItem no state manager. O atom items mudou. O total computado recalculo porque sua dependência mudou. O cartSummary, que também lê do mesmo manager, re-renderiza automaticamente. Zero eventos, zero props passadas pelo container.
E os Built-in Lightning State Managers?
A Salesforce também entrega state managers prontos que envolvem o Lightning Data Service (LDS). Eles seguem o mesmo padrão que os que você escreve, mas já vêm com a integração com dados reais do Salesforce.
Alguns exemplos do que já está disponível:
lightning/stateManagerRecord— para registrar e observar um registro específicolightning/stateManagerObjectInfo— para metadados de objeto (campos, relacionamentos)lightning/stateManagerPageLayout— para layouts de páginalightning/stateManagerRelatedList— para listas relacionadas
Esses managers built-in participam do sistema de cache, normalização e subscriptions do LDS. Se você precisa de dados que já estão no LDS, use esses antes de criar o seu próprio. Eles economizam chamadas de servidor e já respeitam compartilhamento e segurança.
import { LightningElement } from 'lwc';
import recordState from 'lightning/stateManagerRecord';
export default class AccountHeader extends LightningElement {
record = recordState({ recordId: '001XXXXXXXXXXXXXXX' });
get accountName() {
return this.record.value?.fields?.Name?.value;
}
}Quando Usar State Managers — e Quando Não Usar
Uma ferramenta nova convida ao uso excessivo. State Managers resolvem uma classe específica de problema: estado compartilhado e mutável dentro de uma árvore de componentes conectados em uma única página.
Use state managers quando:
- Vários componentes na mesma página leem e escrevem os mesmos dados
- A árvore de componentes é profunda e prop drilling virou um fardo
- Dois componentes irmãos precisam se manter sincronizados
- Você quer uma fonte única da verdade sem duplicar a lógica de dados em cada componente
- Você precisa de valores derivados (computed) que recalcula automaticamente
Não use state managers quando:
- Os dados são específicos de um único componente e não precisam ser compartilhados
- A comunicação cruza limites de página ou regiões do Lightning App Builder — nesse caso, LMS ainda é a ferramenta certa
- Você só precisa passar um valor de pai para filho direto — uma propriedade pública ainda é mais simples
- Você está consumindo dados que o
@wirejá resolve de forma eficiente
Uma boa regra prática: comece com props e eventos, e migre para state manager quando sentir a dor de manter a teia de fiação crescendo. Não force state manager onde uma propriedade pública resolve.
Impacto para Desenvolvedores e Empresas
Para times de desenvolvimento, state managers representam uma mudança de paradigma sutil mas profunda. Pela primeira vez no LWC, você tem uma camada de dados que não está acoplada a componentes. Isso significa que você pode testar a lógica de estado isoladamente, sem montar uma árvore de componentes inteira.
Para empresas, o impacto aparece em dois lugares: manutenibilidade e performance. Código com state managers é mais fácil de refatorar porque mover um componente não quebra a cadeia de props. E com menos round trips ao servidor — já que os dados não precisam ser buscados de novo para cada componente — páginas complexas ficam mais rápidas.
O cenário mais comum que já estamos vendo na comunidade é o de dashboards de oportunidade com múltiplos cards que mostram totais, gráficos e listas de produtos. Antes, cada card fazia sua própria query ou dependia de eventos frágeis. Com state managers, o container busca os dados uma vez e cada card lê do estado compartilhado. O resultado é código mais enxuto e uma página que responde mais rápido.
Limitações Conhecidas (Summer ’26)
Nenhuma ferramenta nasce perfeita. State Managers no Summer ’26 têm algumas limitações que você precisa conhecer antes de adotar:
- Não funciona em Experience Cloud (LWR sites) no momento — a Salesforce confirmou que o recurso roda em Lightning Experience e no aplicativo mobile, mas ainda não em sites Experience Cloud
- Requer API 67.0 — você precisa atualizar o
apiVersionnojs-meta.xmldo seu componente para 67.0 - Não substitui completamente LMS — para comunicação entre componentes em diferentes regiões do App Builder, LMS ainda é o caminho
A expectativa é que essas lacunas sejam fechadas nas próximas releases.
Conclusão
State Managers para LWC no Summer ’26 não são apenas mais uma feature na lista de release notes. Eles resolvem um problema real que todo desenvolvedor Salesforce que já montou uma página com três componentes conhece: como compartilhar estado sem criar uma teia de eventos e props.
A API é limpa, as primitivas (atom, computed, setAtom) são poucas e intuitivas, e a integração com o sistema de reatividade do LWC significa que você não precisa aprender um framework novo para começar a usar. Além disso, os built-in state managers para LDS já entregam valor imediato para casos comuns como exibir registros e metadados.
Se você está começando agora, a dica é: pegue um cenário real onde você tem dois componentes que brigam pelo mesmo dado. Extraia a lógica para um state manager. Veja quantas linhas de código somem. Depois me conta se você consegue voltar atrás.
Os fontes oficiais estão no guia do desenvolvedor LWC e no repositório lwc-recipes no GitHub, que já tem exemplos funcionais de state managers com oportunidades. Vale a leitura.
