VTEX — hooks
useCart, useUser, useWishlist, useAutocomplete; legacy createUse* factories.
@decocms/apps/vtex/hooks provê hooks React para as interações de UI commerce mais comuns. Embrulham invoke com TanStack Query para que cache, refetching e mutações otimistas sejam pagos uma vez.
Import
import {
useCart,
useUser,
useWishlist,
useAutocomplete,
} from "@decocms/apps/vtex/hooks";
useCart
const {
data: cart,
isLoading,
addItems,
updateItems,
removeItems,
applyCoupon,
changeRegion,
isMutating,
} = useCart();
Estado do carrinho + mutações. Comportamento embutido:
- Carregamento eager quando o hook monta (a menos que
enabled: false). - Atualizações otimistas em adicionar/remover/atualizar.
- Auto-refetch após qualquer mutação para reconciliar com o server.
- Refetch em focus (toggle) — desabilitado por default.
Padrão de uso em um botão “adicionar ao carrinho”:
function AddToCartButton({ sku }: { sku: string }) {
const { addItems, isMutating } = useCart();
return (
<button
onClick={() => addItems([{ id: sku, quantity: 1 }])}
disabled={isMutating}
>
{isMutating ? "Adicionando..." : "Adicionar ao carrinho"}
</button>
);
}
useUser
const {
data: user,
isLoading,
signIn,
signOut,
signUp,
} = useUser();
Estado de auth + ações.
function AccountWidget() {
const { data: user, signOut } = useUser();
if (!user) return <SignInLink />;
return <span>Olá, {user.firstName} <button onClick={signOut}>Sair</button></span>;
}
useWishlist
const {
data: wishlist,
isLoading,
add,
remove,
toggle,
has,
} = useWishlist();
has(productId) devolve booleano sincronamente do estado em cache. toggle(productId) adiciona ou remove de acordo.
useAutocomplete
Para o input do header de busca:
const { data, isLoading } = useAutocomplete(query, { enabled: query.length >= 2 });
Devolve { products: Product[]; suggestions: string[] } .
useAutocomplete é debounced internamente (200ms) — chame em todo keystroke; ele é safe.
Por que esses hooks?
Em v1, lojas frequentemente reimplementavam useCart no zero porque o context provider do Preact era escasso. v2 traz o hook plataforma-canônico, então toda loja tem o mesmo comportamento de cache e a mesma forma de mutação otimista de graça.
Se sua loja v1 customizou useCart (e.g. para mostrar loading states diferentes), porte essa lógica como wrapper:
import { useCart as useCartBase } from "@decocms/apps/vtex/hooks";
export function useCart() {
const cart = useCartBase();
return {
...cart,
isLoadingFirstTime: cart.isLoading && !cart.data,
};
}
Legacy: factories createUse*
@decocms/apps/vtex/hooks/legacy ainda exporta:
import { createUseCart, createUseUser } from "@decocms/apps/vtex/hooks/legacy";
Eram a forma de extensibilidade no v1 (embrulhar o hook com transformação custom). Mantidas para compat de migração; prefira embrulhar os hooks novos diretamente.
TanStack Query por baixo
Todo hook usa um query key específico:
| Hook | Query key |
|---|---|
useCart | ["vtex", "cart"] |
useUser | ["vtex", "user"] |
useWishlist | ["vtex", "wishlist"] |
useAutocomplete | ["vtex", "autocomplete", query] |
Use as keys para invalidar manualmente:
import { useQueryClient } from "@tanstack/react-query";
const qc = useQueryClient();
qc.invalidateQueries({ queryKey: ["vtex", "cart"] });
Útil quando uma mutação fora do hook (e.g. submit de form) deve refletir no carrinho.
SSR e hidratação
Hooks chamam invoke que posta para /deco/invoke . No SSR, invoke é resolvido via RequestContext (sem round trip de rede). No client, vira fetch normal.
O resultado: hooks “funcionam” em ambos os ambientes, mas dados de SSR são tipicamente mais frescos. Por isso o cliente que se hidrata pode trocar — TanStack Query trata isso via revalidação default em mount.
Hidratação de carrinho zumbi
Bug clássico: SSR vê cookie do orderForm, render cart.items.length === 3 . Hidratação client-side fetcha sem o cookie (e.g. browsers terceiros bloqueando), render cart.items.length === 0 . UI “atualiza” para vazio.
Mitigação:
- Defina
staleTime: 30_000emuseCartpara mudança de UI ser bloqueada na primeira hidratação. - Em ambientes server-render-known-different, vire o hook com
enabled: falsee oba viauseStatena hidratação inicial.
@decocms/apps/vtex/middleware/cookies cuida da maioria dos casos automaticamente — veja VTEX gotchas.
Veja também
Found an error or want to improve this page?
Edit this page