Pular para o conteúdo principal

State Management

O template usa Zustand para estado client-side e React Router loaders para dados server-side.

Zustand Stores

auth.ts

interface AuthState {
token: string | null;
user: AuthUser | null;
userInfo: AuthUserInfo | null;
isAuthenticated: boolean;
authModal: 'login' | 'register' | null;
refreshState: TokenRefreshState;

setAuth(token: string, user: AuthUser, userInfo: AuthUserInfo): void;
clearAuth(): void;
setAuthModal(modal: 'login' | 'register' | null): void;
hydrateFromCookie(): void;
checkTokenRefresh(callback: () => Promise<void>): void;
}

Principais ações:

  • setAuth() — salva token + user + userInfo, marca isAuthenticated: true
  • clearAuth() — limpa tudo, deleta cookie
  • hydrateFromCookie() — lê token do cookie e seta no store
  • setAuthModal() — controla qual modal está aberto

layout.ts

interface LayoutState {
mobileMenuOpen: boolean;
setMobileMenuOpen(open: boolean): void;
toggleMobileMenu(): void;
}

React Router Loaders (server-side)

Dados que vêm do server (brand, clientEnv) são carregados via loader e passados via props/context. Não ficam no Zustand.

// _layout.tsx
export async function loader({ context }: Route.LoaderArgs) {
const brand = await loadBrandConfig(env);
const clientEnv = { ... };
return { brand, clientEnv };
}

Padrão de acesso

  • Server data (brand, config): useBrand(), useClientEnv() — via React Context
  • Client state (auth, layout): useAuthStore(), useLayoutStore() — via Zustand
  • Modais: controlados por authModal no auth store — qualquer componente pode abrir/fechar