Client-Side Data Fetching
Patterns
1. Supabase Client Direct Queries
'use client';
import { createClient } from '@/lib/supabase/client';
export function MyComponent() {
const [data, setData] = useState([]);
useEffect(() => {
async function fetchData() {
const supabase = createClient(); // Browser client
const { data } = await supabase
.from('campaigns')
.select('*');
setData(data);
}
fetchData();
}, []);
return <div>{/* Render data */}</div>;
}
2. Custom Hooks for Data Fetching
// hooks/useFetchUsersList.tsx
'use client';
export function useFetchUsersList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
setLoading(true);
const supabase = createClient();
const { data } = await supabase.from('users').select('*');
setUsers(data);
setLoading(false);
};
return { users, loading, refetch: fetchUsers };
}
3. Fetch API for External Services
'use client';
const searchVoter = async (params) => {
const response = await fetch('/api/essearch', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ params }),
});
return response.json();
};
Client-Side Caching
The useFetchTableData hook implements client-side caching:
const cache = useRef<Record<string, { data: any[]; count: number }>>({});
const fetchData = useCallback(async (force = false) => {
const cacheKey = generateCacheKey(filters, sorting, pagination);
// Check cache first
if (!force && cache.current[cacheKey]) {
setData(cache.current[cacheKey].data);
return;
}
// Fetch and cache
const { data } = await query;
cache.current[cacheKey] = { data, count };
setData(data);
}, [filters, sorting, pagination]);