State in SPFx: External Data (SharePoint, Graph)

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 loading and error alongside data.
  • 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.