Title here
Summary here
Haddock uses a multi-layered approach to state management:
import { create } from 'zustand'
interface AppState {
theme: 'light' | 'dark'
setTheme: (theme: 'light' | 'dark') => void
sidebarOpen: boolean
setSidebarOpen: (open: boolean) => void
}
export const useAppStore = create<AppState>((set) => ({
theme: 'light',
setTheme: (theme) => set({ theme }),
sidebarOpen: false,
setSidebarOpen: (open) => set({ sidebarOpen: open })
}))
import { useAppStore } from '@/stores/app'
function ThemeToggle() {
const { theme, setTheme } = useAppStore()
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
)
}
import { useQuery, useMutation } from '@tanstack/react-query'
// Query hook
export function useProjects() {
return useQuery({
queryKey: ['projects'],
queryFn: fetchProjects
})
}
// Mutation hook
export function useCreateProject() {
return useMutation({
mutationFn: createProject,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['projects'] })
}
})
}
function ProjectList() {
const { data: projects, isLoading } = useProjects()
if (isLoading) return <LoadingSpinner />
return (
<div>
{projects?.map(project => (
<ProjectCard key={project.id} project={project} />
))}
</div>
)
}
import { createContext, useContext } from 'react'
const AuthContext = createContext<AuthContextType | null>(null)
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null)
return (
<AuthContext.Provider value={{ user, setUser }}>
{children}
</AuthContext.Provider>
)
}
function UserProfile() {
const { user } = useAuth()
if (!user) return <LoginPrompt />
return <div>Welcome, {user.name}</div>
}
interface SocketStore {
connected: boolean
messages: Message[]
connect: () => void
disconnect: () => void
send: (message: Message) => void
}
export const useSocketStore = create<SocketStore>((set) => ({
connected: false,
messages: [],
connect: () => {
// WebSocket connection logic
},
disconnect: () => {
// Disconnect logic
},
send: (message) => {
// Send message logic
}
}))
Global State (Zustand)
Server State (React Query)
Context
Local State
State Splitting
// Split into smaller stores
const useUIStore = create<UIState>()
const useAuthStore = create<AuthState>()
Selective Updates
// Use selectors
const theme = useAppStore(state => state.theme)
Middleware
const log = (config) => (set, get, api) => config(
(...args) => {
console.log('Before', get())
set(...args)
console.log('After', get())
},
get,
api
)
const { data, error } = useQuery({
queryKey: ['projects'],
queryFn: fetchProjects,
retry: 3,
onError: (error) => {
toast({
title: 'Error',
description: error.message
})
}
})