Dansk

Lås op for effektiv datahentning i React med Suspense! Udforsk forskellige strategier, fra indlæsning på komponentniveau til parallel datahentning, og byg responsive, brugervenlige applikationer.

React Suspense: Strategier til datahentning i moderne applikationer

React Suspense er en kraftfuld funktion introduceret i React 16.6, der forenkler håndteringen af asynkrone operationer, især datahentning. Det giver dig mulighed for at "suspendere" komponentgengivelse, mens du venter på, at data indlæses, hvilket giver en mere deklarativ og brugervenlig måde at administrere indlæsningstilstande på. Denne guide udforsker forskellige strategier til datahentning ved hjælp af React Suspense og giver praktiske indsigter i at bygge responsive og performante applikationer.

Forståelse af React Suspense

Før vi dykker ned i specifikke strategier, lad os forstå de grundlæggende koncepter i React Suspense:

Strategier til datahentning med Suspense

Her er flere effektive strategier til datahentning ved hjælp af React Suspense:

1. Datahentning på komponentniveau

Dette er den mest ligetil tilgang, hvor hver komponent henter sine egne data inden for en Suspense-grænse. Den er velegnet til simple komponenter med uafhængige datakrav.

Eksempel:

Lad os sige, vi har en UserProfile-komponent, der skal hente brugerdata fra et API:

// Et simpelt værktøj til datahentning (erstat med dit 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>Indlæser brugerdata...</div>}>
      <UserProfile />
    </Suspense>
  );
}

Forklaring:

Fordele:

Ulemper:

2. Parallel datahentning

For at undgå vandfalds-hentning kan du starte flere dataanmodninger samtidigt og bruge Promise.all eller lignende teknikker til at vente på dem alle, før komponenterne gengives. Dette minimerer den samlede indlæsningstid.

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>Email: {user.email}</p>
      <h3>Indlæg:</h3>
      <ul>
        {posts.map(post => (<li key={post.id}>{post.title}</li>))}
      </ul>
    </div>
  );
}

function App() {
  return (
    <Suspense fallback={<div>Indlæser brugerdata og indlæg...</div>}>
      <UserProfile />
    </Suspense>
  );
}

Forklaring:

Fordele:

Ulemper:

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

Når man bruger Server-Side Rendering (SSR), kan Suspense bruges til selektivt at hydrere dele af siden. Dette betyder, at du kan prioritere hydrering af de vigtigste dele af siden først, hvilket forbedrer Time to Interactive (TTI) og den opfattede ydeevne. Dette er nyttigt i scenarier, hvor du ønsker at vise det grundlæggende layout eller kerneindhold så hurtigt som muligt, mens hydrering af mindre kritiske komponenter udsættes.

Eksempel (Konceptuelt):

// Server-side:
<Suspense fallback={<div>Indlæser kritisk indhold...</div>}>
  <CriticalContent />
</Suspense>
<Suspense fallback={<div>Indlæser valgfrit indhold...</div>}>
  <OptionalContent />
</Suspense>

Forklaring:

Fordele:

Ulemper:

4. Datahentningsbiblioteker med Suspense-understøttelse

Flere populære datahentningsbiblioteker har indbygget understøttelse for React Suspense. Disse biblioteker giver ofte en mere bekvem og effektiv måde at hente data på og integrere med Suspense. Nogle bemærkelsesværdige 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>indlæsning mislykkedes</div>
  if (!user) return <div>indlæser...</div> // Dette bliver sandsynligvis aldrig gengivet med Suspense

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

function App() {
  return (
    <Suspense fallback={<div>Indlæser brugerdata...</div>}>
      <UserProfile />
    </Suspense>
  );
}

Forklaring:

Fordele:

Ulemper:

Fejlhåndtering med Suspense

Fejlhåndtering er afgørende, når man bruger Suspense. React tilbyder en ErrorBoundary-komponent til at fange fejl, der opstår inden for Suspense-grænser.

Eksempel:

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

  static getDerivedStateFromError(error) {
    // Opdater tilstand, så den næste gengivelse viser fallback-UI'en.
    return { hasError: true };
  }

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

  render() {
    if (this.state.hasError) {
      // Du kan gengive enhver brugerdefineret fallback-UI
      return <h1>Noget gik galt.</h1>;
    }

    return this.props.children; 
  }
}

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

Forklaring:

Bedste praksis for brug af React Suspense

Eksempler fra den virkelige verden

React Suspense kan anvendes i forskellige scenarier, herunder:

Eksempel 1: International e-handelsplatform

Forestil dig en e-handelsplatform, der betjener kunder i forskellige lande. Produktdetaljer, såsom priser og beskrivelser, skal muligvis hentes baseret på brugerens placering. Suspense kan bruges til at vise en indlæsningsindikator, mens de lokaliserede produktoplysninger 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(); // Funktion til at bestemme brugerens lokalitet
  return (
    <Suspense fallback={<div>Indlæser produktdetaljer...</div>}>
      <ProductDetails productId="123" locale={userLocale} />
    </Suspense>
  );
}

Eksempel 2: Globalt feed til sociale medier

Overvej en social medieplatform, der viser et feed af indlæg fra brugere over hele verden. Hvert indlæg kan indeholde tekst, billeder og videoer, som kan tage varierende tid at indlæse. Suspense kan bruges til at vise pladsholdere for individuelle indlæg, mens deres indhold indlæses, hvilket giver en mere jævn rulleoplevelse.

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(); // Funktion til at hente en liste over post-ID'er
  return (
    <div>
      {postIds.map(postId => (
        <Suspense key={postId} fallback={<div>Indlæser indlæg...</div>}>
          <Post postId={postId} />
        </Suspense>
      ))}
    </div>
  );
}

Konklusion

React Suspense er et kraftfuldt værktøj til at administrere asynkron datahentning i React-applikationer. Ved at forstå de forskellige datahentningsstrategier og bedste praksis kan du bygge responsive, brugervenlige og performante applikationer, der leverer en fantastisk brugeroplevelse. Eksperimenter med forskellige strategier og biblioteker for at finde den bedste tilgang til dine specifikke behov.

I takt med at React fortsætter med at udvikle sig, vil Suspense sandsynligvis spille en endnu større rolle i datahentning og gengivelse. At holde sig informeret om de seneste udviklinger og bedste praksis vil hjælpe dig med at udnytte det fulde potentiale af denne funktion.