State Management
The app uses Zustand for state management with persistence via expo-secure-store.
Auth Store
The primary store handles authentication state.
Location
stores/authStore.ts
State Shape
typescript
interface AuthState {
// Auth
user: User | null
session: Session | null
isAuthenticated: boolean
isLoading: boolean
// Onboarding
onboardingStep: number
onboardingData: OnboardingData
// Actions
signIn: (email: string) => Promise<void>
verifyMagicLink: (token: string) => Promise<void>
signOut: () => Promise<void>
setOnboardingStep: (step: number) => void
}Usage
typescript
import { useAuthStore } from "@/stores/authStore"
function ProfileScreen() {
const { user, signOut } = useAuthStore()
return (
<View>
<Text>{user?.email}</Text>
<Button onPress={signOut}>Sign Out</Button>
</View>
)
}Selectors
For performance, select only what you need:
typescript
// Good - only re-renders when user changes
const user = useAuthStore((state) => state.user)
// Avoid - re-renders on any state change
const { user, session, isLoading } = useAuthStore()Persistence
Sensitive data is stored securely:
typescript
import * as SecureStore from "expo-secure-store"
// The store middleware handles persistence
const useAuthStore = create(
persist(
(set) => ({
// state & actions
}),
{
name: "auth-storage",
storage: createSecureStorage(),
}
)
)Creating New Stores
typescript
import { create } from "zustand"
import { persist } from "zustand/middleware"
interface BookState {
currentlyReading: Book[]
addBook: (book: Book) => void
removeBook: (bookId: string) => void
}
export const useBookStore = create<BookState>()(
persist(
(set) => ({
currentlyReading: [],
addBook: (book) =>
set((state) => ({
currentlyReading: [...state.currentlyReading, book],
})),
removeBook: (bookId) =>
set((state) => ({
currentlyReading: state.currentlyReading.filter(
(b) => b.id !== bookId
),
})),
}),
{
name: "book-storage",
}
)
)Best Practices
- Keep stores focused - One store per domain (auth, books, settings)
- Use selectors - Avoid re-renders by selecting specific state
- Actions in store - Keep state mutations inside the store
- Persist wisely - Only persist necessary data
- Secure sensitive data - Use SecureStore for tokens