Norsk

Frigjør effektiv datahenting i React med Suspense! Utforsk ulike strategier, fra lasting på komponentnivå til parallell datahenting, og bygg responsive, brukervennlige applikasjoner.

React Suspense: Strategier for datahenting i moderne applikasjoner

React Suspense er en kraftig funksjon introdusert i React 16.6 som forenkler håndtering av asynkrone operasjoner, spesielt datahenting. Den lar deg "utsette" (suspend) rendring av komponenter mens du venter på at data skal lastes, noe som gir en mer deklarativ og brukervennlig måte å håndtere lastetilstander på. Denne guiden utforsker ulike strategier for datahenting ved hjelp av React Suspense og gir praktisk innsikt i hvordan man bygger responsive og ytelsessterke applikasjoner.

Forstå React Suspense

Før vi dykker inn i spesifikke strategier, la oss forstå kjernekonseptene i React Suspense:

Strategier for datahenting med Suspense

Her er flere effektive strategier for datahenting ved hjelp av React Suspense:

1. Datahenting på komponentnivå

Dette er den enkleste tilnærmingen, der hver komponent henter sine egne data innenfor en Suspense-grense. Den passer for enkle komponenter med uavhengige datakrav.

Eksempel:

La oss si vi har en UserProfile-komponent som trenger å hente brukerdata fra et API:

// Et enkelt verktøy for datahenting (erstatt med ditt foretrukne bibliotek)
const fetchData = (url) => {
  let status = 'pending';
  let result;
  let suspender = fetch(url)
    .then(res => {
      if (!res.ok) {
        throw new Error(`HTTP error! Status: ${res.status}`);
      }
      return res.json();
    })
    .then(
      res => {
        status = 'success';
        result = res;
      },
      err => {
        status = 'error';
        result = err;
      }
    );

  return {
    read() {
      if (status === 'pending') {
        throw suspender;
      } else if (status === 'error') {
        throw result;
      }
      return result;
    }
  };
};

const userResource = fetchData('/api/user/123');

function UserProfile() {
  const user = userResource.read();
  return (
    <div>
      <h2>{user.name}</h2>
      <p>Email: {user.email}</p>
    </div>
  );
}

function App() {
  return (
    <Suspense fallback={<div>Laster brukerdata...</div>}>
      <UserProfile />
    </Suspense>
  );
}

Forklaring:

Fordeler:

Ulemper:

2. Parallell datahenting

For å unngå fossefall-henting kan du starte flere dataforespørsler samtidig og bruke Promise.all eller lignende teknikker for å vente på alle før du rendrer komponentene. Dette minimerer den totale lastetiden.

Eksempel:

const userResource = fetchData('/api/user/123');
const postsResource = fetchData('/api/user/123/posts');

function UserProfile() {
  const user = userResource.read();
  const posts = postsResource.read();

  return (
    <div>
      <h2>{user.name}</h2>
      <p>E-post: {user.email}</p>
      <h3>Innlegg:</h3>
      <ul>
        {posts.map(post => (<li key={post.id}>{post.title}</li>))}
      </ul>
    </div>
  );
}

function App() {
  return (
    <Suspense fallback={<div>Laster brukerdata og innlegg...</div>}>
      <UserProfile />
    </Suspense>
  );
}

Forklaring:

Fordeler:

Ulemper:

3. Selektiv hydrering (for Server-Side Rendering - SSR)

Når du bruker Server-Side Rendering (SSR), kan Suspense brukes til å selektivt hydrere deler av siden. Dette betyr at du kan prioritere hydrering av de viktigste delene av siden først, noe som forbedrer Time to Interactive (TTI) og opplevd ytelse. Dette er nyttig i scenarier der du vil vise det grunnleggende oppsettet eller kjerneinnholdet så raskt som mulig, mens du utsetter hydrering av mindre kritiske komponenter.

Eksempel (konseptuelt):

// På serversiden:
<Suspense fallback={<div>Laster kritisk innhold...</div>}>
  <CriticalContent />
</Suspense>
<Suspense fallback={<div>Laster valgfritt innhold...</div>}>
  <OptionalContent />
</Suspense>

Forklaring:

Fordeler:

Ulemper:

4. Datahentingsbiblioteker med Suspense-støtte

Flere populære datahentingsbiblioteker har innebygd støtte for React Suspense. Disse bibliotekene gir ofte en mer praktisk og effektiv måte å hente data på og integrere med Suspense. Noen nevneverdige eksempler inkluderer:

Eksempel (med SWR):

import useSWR from 'swr'

const fetcher = (...args) => fetch(...args).then(res => res.json())

function UserProfile() {
  const { data: user, error } = useSWR('/api/user/123', fetcher, { suspense: true })

  if (error) return <div>kunne ikke laste</div>
  if (!user) return <div>laster...</div> // Dette blir sannsynligvis aldri rendret med Suspense

  return (
    <div>
      <h2>{user.name}</h2>
      <p>E-post: {user.email}</p>
    </div>
  )
}

function App() {
  return (
    <Suspense fallback={<div>Laster brukerdata...</div>}>
      <UserProfile />
    </Suspense>
  );
}

Forklaring:

Fordeler:

Ulemper:

Feilhåndtering med Suspense

Feilhåndtering er avgjørende når du bruker Suspense. React tilbyr en ErrorBoundary-komponent for å fange feil som oppstår innenfor Suspense-grensene.

Eksempel:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Oppdater state slik at neste render vil vise fallback-UI-et.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // Du kan også logge feilen til en feilrapporteringstjeneste
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // Du kan rendre hvilket som helst tilpasset fallback-UI
      return <h1>Noe gikk galt.</h1>;
    }

    return this.props.children; 
  }
}

function App() {
  return (
    <ErrorBoundary>
      <Suspense fallback={<div>Laster...</div>}>
        <UserProfile />
      </Suspense>
    </ErrorBoundary>
  );
}

Forklaring:

Beste praksis for bruk av React Suspense

Eksempler fra den virkelige verden

React Suspense kan brukes i ulike scenarier, inkludert:

Eksempel 1: Internasjonal e-handelsplattform

Se for deg en e-handelsplattform som betjener kunder i forskjellige land. Produktdetaljer, som priser og beskrivelser, må kanskje hentes basert på brukerens plassering. Suspense kan brukes til å vise en lasteindikator mens den lokaliserte produktinformasjonen hentes.

function ProductDetails({ productId, locale }) {
  const productResource = fetchData(`/api/products/${productId}?locale=${locale}`);
  const product = productResource.read();

  return (
    <div>
      <h2>{product.name}</h2>
      <p>Pris: {product.price}</p>
      <p>Beskrivelse: {product.description}</p>
    </div>
  );
}

function App() {
  const userLocale = getUserLocale(); // Funksjon for å bestemme brukerens lokalitet
  return (
    <Suspense fallback={<div>Laster produktdetaljer...</div>}>
      <ProductDetails productId="123" locale={userLocale} />
    </Suspense>
  );
}

Eksempel 2: Global sosial medier-feed

Tenk deg en sosial medieplattform som viser en feed med innlegg fra brukere over hele verden. Hvert innlegg kan inneholde tekst, bilder og videoer, som kan ta ulik tid å laste. Suspense kan brukes til å vise plassholdere for individuelle innlegg mens innholdet deres lastes, noe som gir en jevnere rulleopplevelse.

function Post({ postId }) {
  const postResource = fetchData(`/api/posts/${postId}`);
  const post = postResource.read();

  return (
    <div>
      <p>{post.text}</p>
      {post.image && <img src={post.image} alt="Post Image" />}
      {post.video && <video src={post.video} controls />}
    </div>
  );
}

function App() {
  const postIds = getPostIds(); // Funksjon for å hente en liste over innleggs-IDer
  return (
    <div>
      {postIds.map(postId => (
        <Suspense key={postId} fallback={<div>Laster innlegg...</div>}>
          <Post postId={postId} />
        </Suspense>
      ))}
    </div>
  );
}

Konklusjon

React Suspense er et kraftig verktøy for å håndtere asynkron datahenting i React-applikasjoner. Ved å forstå de ulike datahentingsstrategiene og beste praksis, kan du bygge responsive, brukervennlige og ytelsessterke applikasjoner som leverer en flott brukeropplevelse. Eksperimenter med forskjellige strategier og biblioteker for å finne den beste tilnærmingen for dine spesifikke behov.

Ettersom React fortsetter å utvikle seg, vil Suspense sannsynligvis spille en enda viktigere rolle i datahenting og rendring. Å holde seg informert om de siste utviklingene og beste praksis vil hjelpe deg med å utnytte det fulle potensialet til denne funksjonen.