State in SPFx: External Data (SharePoint, Graph)
Fetch from SharePoint REST/Graph, caching strategies, and effects composition in SPFx.
Data fetching patterns
- Co-locate fetching with the component that needs it; elevate to a custom hook if reused.
- Track
loadinganderroralongsidedata. - Cancel in-flight requests on unmount or parameter change.
- Consider light caching (memoized responses) or libraries like SWR/React Query for advanced needs.
SharePoint REST example (with cancellation)
type TasksResponse = { value: { id: number; Title: string }[] };
const [data, setData] = useState<TasksResponse | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const ac = new AbortController();
(async () => {
try {
setLoading(true);
const res = await fetch(`${siteUrl}/_api/web/lists/getbytitle('Tasks')/items`, { signal: ac.signal });
const json = await res.json();
setData(json as TasksResponse);
} catch (e: any) {
if (e.name !== 'AbortError') setError(e.message);
} finally {
setLoading(false);
}
})();
return () => ac.abort();
}, [siteUrl]);
Microsoft Graph example
type UsersResponse = { value: { id: string; displayName: string }[] };
const { data, loading, error } = useCancelableFetch<UsersResponse>(`${graphBase}/v1.0/users?$top=20`, [graphBase]);
Transforming and normalizing data
Keep transformation outside state; derive views from raw data.
const tasks = data?.value ?? [];
const openTasks = tasks.filter(t => !t.isClosed);
Error UI patterns
Render friendly, actionable messages; log details in Application Insights if configured.
if (error) return <MessageBar intent="error">Failed to load tasks. Try again.</MessageBar>;
Caching and revalidation
For frequently accessed lists, introduce a simple cache key by URL or switch to a library (SWR/React Query) for stale‑while‑revalidate.