DEV Community

Cover image for Sincronizando Zustand com VTEX OrderForm no React Native
Carlos Rogerio Orioli
Carlos Rogerio Orioli

Posted on

Sincronizando Zustand com VTEX OrderForm no React Native

Recentemente, precisei desenvolver uma integração de checkout VTEX dentro de um aplicativo React Native. O desafio era garantir que a experiência de compra fosse fluida, mantendo o estado do carrinho perfeitamente sincronizado entre o ambiente nativo do app e a finalização da compra na WebView.

Para resolver isso, utilizei o Zustand para o gerenciamento de estado global e a API de Checkout da VTEX para manipular o orderFormId.

A Arquitetura da Solução

A ideia central foi: o App gerencia os produtos e quantidades através de uma store leve Zustand e, antes de abrir o checkout, sincronizamos tudo com a VTEX via API.

1. Gerenciando o Carrinho com Zustand

A store armazena o orderFormId e persiste os dados para que o carrinho não se perca. Aqui, podemos escolher entre o AsyncStorage (padrão) ou o MMKV (para performance ultra-rápida).

import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { MMKV } from 'react-native-mmkv';

// Opção com MMKV (Alta Performance)
const storage = new MMKV();
const mmkvStorage = {
  setItem: (name, value) => storage.set(name, value),
  getItem: (name) => storage.getString(name) ?? null,
  removeItem: (name) => storage.delete(name),
};

export const useCartStore = create(
  persist(
    (set) => ({
      orderFormId: null,
      items: [],
      setOrderFormId: (id) => set({ orderFormId: id }),
      addToCart: (item) => set((state) => ({ items: [...state.items, item] })),
      clearCart: () => set({ items: [], orderFormId: null }),
    }),
    {
      name: 'cart-storage',
      // Troque 'mmkvStorage' por 'AsyncStorage' se preferir o padrão
      storage: createJSONStorage(() => mmkvStorage), 
    }
  )
);
Enter fullscreen mode Exit fullscreen mode

Para esse projeto, utilizei o MMKV pela velocidade de leitura/escrita, mas a estrutura funciona perfeitamente com AsyncStorage também.

2. Sincronizando com a API da VTEX

Antes de navegar para a tela de checkout, enviamos os itens para o orderForm específico. Isso evita disparar várias chamadas de rede desnecessárias durante a navegação.

const syncCartWithVtex = async (orderFormId, items) => {
  try {
    await fetch(`https://{ACCOUNT}.vtexcommercestable.com.br/api/checkout/pub/orderForm/${orderFormId}/items`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        orderItems: items.map(i => ({ id: i.id, quantity: i.quantity, seller: "1" }))
      }),
    });
  } catch (error) {
    console.error("Erro na sincronização:", error);
  }
};
Enter fullscreen mode Exit fullscreen mode

DICA: A VTEX às vezes exige que o cabeçalho vtex-id-client-authtoken seja enviado se o usuário já estiver autenticado no app, para que o carrinho não fique como "anônimo"

3. O Checkout na WebView

A sacada foi é injetar o orderFormId na URL da WebView. Assim, o checkout da VTEX já abre com todos os itens que o usuário escolheu no app.

import { WebView } from 'react-native-webview';

const VtexCheckout = () => {
  const { orderFormId } = useCartStore();

  // URL que vincula a sessão ao carrinho do App
  const checkoutUrl = `https://www.sualoja.com.br/checkout/?orderFormId=${orderFormId}#/cart`;

  return (
    <WebView 
      source={{ uri: checkoutUrl }}
      sharedCookiesEnabled={true} //PARA MANTER A SESSÃO 
      startInLoadingState={true}
    />
  );
};
Enter fullscreen mode Exit fullscreen mode

Lições aprendidas

Performance: Sincronizar o estado via API antes de abrir a WebView entrega uma experiência muito mais "nativa" do que tentar manipular o DOM da página carregada.

  • Persistência: O uso do Zustand com middleware de persistência é imbatível para lidar com carrinhos em dispositivos móveis.

  • Desenvolver soluções de e-commerce de alta performance é o que move a gente na Converte .

E você, já teve que lidar com essa ponte entre o nativo e o web no e-commerce? Vamos trocar uma ideia nos comentários!

Top comments (0)