TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸

Evolution of React code

December 11, 2023

Evolution von React Code (kurz)

React Code ist ueber die Jahre einfacher und deklarativer geworden: von "fetch in useEffect" zu spezialisierten Data Libraries und Suspense.

1) Manuelles Fetching mit useEffect

code
function List({ pageId }) {
  const [items, setItems] = useState(null);

  useEffect(() => {
    fetchItems(pageId).then(setItems);
  }, [pageId]);

  if (!items) return null;
  return items[pageId].map((item) => <li key={item.id}>{item.title}</li>);
}

Probleme:

  • Race Conditions bei schnellen pageId Wechseln
  • Viel Boilerplate fuer Loading/Error
  • Kein Caching

2) Data Fetching Libraries

Libraries wie useSWR, React Query, Apollo oder RTK Query kapseln:

  • Laden + Fehler
  • Caching
  • Revalidation
code
function List({ pageId }) {
  const { data, isLoading } = useData(pageId);

  if (isLoading) return <Spinner />;
  return data.items.map((item) => <li key={item.id}>{item.title}</li>);
}

3) Suspense als Loading Boundary

Statt Loading State in jeder Komponente:

code
<Suspense fallback={<Spinner />}>
  <List pageId={pageId} />
</Suspense>

Vorteil:

  • Loading UI an einem Ort
  • Komponenten bleiben "data first" und schlank

Du kannst verschachteln:

code
<Suspense fallback={<Skeleton />}>
  <Header />
  <Suspense fallback={<ListPlaceholder />}>
    <List pageId={pageId} />
  </Suspense>
</Suspense>

Fazit

Der Trend geht zu:

  • weniger manuelle State Verwaltung
  • klare Loading Grenzen
  • wiederverwendbaren Data Hooks