SPFx: Components vs Function Components

SPFx: Components vs Function Components

Clarify the differences and practical guidance for choosing class components or function components (hooks) in SPFx.

TL;DR

  • Prefer function components with hooks for new SPFx work: simpler lifecycle, better composition, easier testing.
  • Keep class components mainly for Error Boundaries (or use a boundary library) and rare useLayoutEffect-style timing needs.
  • Migrate scaffolded class components to function components using the patterns below.

Why function components

  • Effects replace scattered lifecycles with focused, dependency-driven logic.
  • Hooks compose: reuse behaviors via custom hooks (useCancelableFetch, useFormState).
  • Smaller components: derive values with useMemo, stabilize handlers with useCallback.

When class components still make sense

  • Error Boundaries (componentDidCatch): keep a small class boundary or use a library like react-error-boundary.
  • Special DOM measurement timing: prefer useLayoutEffect in functions; otherwise keep tiny class wrapper.

Migration checklist

  • State → useState or useReducer for complex flows.
  • Instance fields → useRef (timers, controllers, mutable caches).
  • Lifecycles → useEffect with cleanups and correct deps.
  • Context usage → provider at container level; pass minimal props to presentational children.

SPFx specifics

  • Property pane updates: debounce heavy work inside effects.
  • Theme changes: subscribe in an effect and clean up on unmount.
  • Keep SPFx Context at the container layer (presentational components stay pure).

See also

  • /blog/reactspfx/90_bonus_01_migrating-class-to-hooks
  • /blog/reactspfx/04_components_02_container-vs-presentational
  • /blog/reactspfx/03_custom-hooks_04_useCancelableFetch