React 18 Felfüggesztett adatok lekérése egy fej nélküli CMS PlatoBlockchain Data Intelligence rendszerből. Függőleges keresés. Ai.

React 18 Felfüggesztett adatok lekérése egy fej nélküli CMS-ből

A webhely nagyszerű felhasználói élményének biztosításához optimalizálnunk kell az első oldal betöltési idejét és az oldal interakciókra való reagálását. Minél gyorsabban reagál az oldal a felhasználói bevitelre – annál jobb.

Reagálj 18 célja az interaktivitás javítása olyan funkciókkal, mint a szelektív hidratálás val vel Suspense hogy a hidratálást akadálymentessé tegyük, és nagyobb átláthatóságot biztosítsunk a mi építészeti a választások hatással lesznek alkalmazásunk felhasználói élményére és teljesítményére. A React 18 jelentős teljesítményjavításokat hajt végre, és támogatja a Suspense a szerveroldali renderelés (SSR) esetén, amely lehetővé teszi az alkalmazások részeinek aszinkron kiszolgálását, az alkalmazás egy lassú részét becsomagolhatja a Suspense összetevőbe, és felszólítja a Reactot, hogy késleltesse a lassú összetevő betöltését.

Reagálj 18 a közelmúltban jelent meg olyan funkciókkal, amelyek az interaktivitás javítását szolgálják. Jellemzők, mint szelektív hidratálás val vel Suspense hogy a hidratálást akadálymentessé tegyük, és nagyobb átláthatóságot biztosítsunk a mi építészeti a választások hatással lesznek alkalmazásunk felhasználói élményére és teljesítményére. A React 18 támogatást nyújt a következőhöz Suspense a szerveroldali renderelés (SSR) esetén, amely lehetővé teszi az alkalmazások részeinek aszinkron kiszolgálását, az alkalmazás egy lassú részét becsomagolhatja a Suspense összetevőbe, és felszólítja a Reactot, hogy késleltesse a lassú összetevő betöltését.

A szerveroldali megjelenítés lehetővé teszi, hogy HTML-kódot generáljon a kiszolgálón lévő React összetevőiből, és elküldje azt a felhasználóknak. Az SSR lehetővé teszi a felhasználók számára, hogy láthassák az oldal tartalmát, mielőtt a JavaScript-csomag betöltődik és lefutna, majd a JavaScript-kód betöltődik és egyesül a HTML-kóddal, eseménykezelőket csatolva – ami hidratáció. A hagyományos HTML streaminggel ellentétben ennek nem kell felülről lefelé haladva történnie.

React-18-Suspense.jpeg
A Suspense, akkor megmondhatja a Reactnak, hogy először küldje el a többi összetevő HTML-kódját, a helyőrző HTML-kódjával együtt, például egy betöltési pörgetőhöz. Jelentősen javítja a felhasználói élményt és a felhasználó által észlelt késleltetést.

Két fő SSR-funkció van benne A React 18 a Suspense által feloldott:

  • HTML streamelése a szerveren.
  • Szelektív hidratálás az ügyfélen.

Fedezzük fel React Adatlekérési megközelítések val vel useEffect és a Suspense próbálja meg összehasonlítani a backend adatlekérő gyakorlati megoldásokat, esetünkben egy gyors és intuitív fej nélküli CMS-t választunk Kozmikus. Kódpéldáinkat egy link segítségével ellenőrizheti StackBlitz.
React18

Integrációs Cosmic Headless CMS

Adatok lekéréséhez használjuk Kozmikus fej nélküli CMS egy csak háttérben működő tartalomkezelő rendszer (CMS) egy csak háttérben működő tartalomkezelő rendszer (CMS), amely az alapoktól a tartalmat elérhetővé tevő tartalomtárként épül fel. A Cosmic integrálásához és értékeinek lekéréséhez telepítenünk kell a Cosmic modult a projektbe.

npm i cosmicjs

yarn add cosmicjs

Ezután hozzon létre egy ingyenes Cosmic fiók és menj Kozmikus műszerfal Your Bucket > Settings > API Access és keresse meg a Bucket slug-ját és az API olvasási kulcsát, és adja hozzá őket a Cosmic Fetch funkció létrehozásához fetchDataByType kérjen a Cosmic vödörbe, és töltse le a létrehozott kategóriák tartalmát Kozmikus lekérdezés típus categories.


import Cosmic from 'cosmicjs';

const bucket = Cosmic().bucket({
  slug: 'your_cosmic_slug',
  read_key: 'your_cosmic_read_key',
});

export async function fetchDataByType(objectType = 'categories') {
  const params = {
    query: {
      type: objectType,
    },
    props: 'title,slug,id,metadata',
    sort: '-created_at',
  };

  try {
    const data = await bucket.getObjects(params);
    return data.objects;
  } catch (error) {
    return { error };
  }
}

A Cosmic hatékony tartalommodellezési funkciókat is kínál, amelyek lehetővé teszik bármilyen tartalom szupergyors és többcsatornás közzétételét, hogy megvalósítsa az egyszeri létrehozást és a közzétételt mindenhol.

Lehívás a rendereléskor

Lehívás a rendereléskor megközelítés a hálózati kérés magában az összetevőben aktiválódik a beillesztés után, a kérés nem indul el addig, amíg az összetevő meg nem jelenik. Ha nem ír olyan tisztítási függvényt, amely figyelmen kívül hagyja az elavult válaszokat, észre fogja venni a versenyfeltétel (In React) hiba, amikor két kissé eltérő adatkérés történt, és az alkalmazás eltérő eredményt jelenít meg attól függően, hogy melyik kérés fejeződik be először. Valójában a React 18-ban, ha engedélyezi a StrictMode-ot az alkalmazásban, akkor fejlesztői módban megtudhatja, hogy a useEffect használata kétszer lesz meghívva, mert most a React felcsatolja az összetevőt, leválasztja, majd újra felcsatolja, hogy ellenőrizze, hogy a kód megfelelően működik.

Javítsunk ki egy adatlekérési versenyfeltételt, kihasználva a useEffect tisztító funkció. Ha több kérést is beadunk, de csak az utolsó eredményt jelenítjük meg, használhatunk logikai jelzőt isMount:


import React, { useEffect, useState } from 'react';
import Category from './components/Category';
import { fetchDataByType } from './cosmic.js';

const App = () => {
  const [categories, setCategories] = useState([]);

  const getCategories = async () => {
    const result = await fetchDataByType('categories');
    if (result.length) {
      setCategories(result);
    }
  };

  useEffect(() => {
    let isMount = true;

    if (isMount) {
      getCategories();
    }

    
    return () => {
      isMount = false;
    };
  }, []);

  return (
    <div className={cn('container', styles.container)}>
     <div className={styles.sidebar}>
      <div className={styles.collections}>
       {categories?.map((category) => (
         <Category key={category.id} info={category} />
        ))}
       </div>
      </div>
     </div>
  );
};

export default App;

Ezen túlmenően, ha egy komponens többször renderelődik (mint általában), az előző effektus törlődik a következő effektus végrehajtása előtt.

Ebben az esetben továbbra is versenyfeltételünk van abban az értelemben, hogy a Cosmic felé több kérés repülés közben lesz, de csak az utolsó eredményét használjuk fel.

FetchWithuseEffect

useEffect

Szintén mint Dan Abramov magyarázza, Lehívás a rendereléskor lassú navigációt biztosít a képernyők között. Ha van szülő és gyermek összetevők mindketten bekerülnek useEffects, akkor a gyermekkomponens el sem tudja kezdeni a letöltést, amíg a szülőkomponens be nem fejezi a letöltést. Az ilyen típusú teljesítményproblémák nagyon gyakoriak az egyoldalas alkalmazásokban, és sokkal több lassúságot okoznak, mint a „túlzott újramegjelenítés”, és ha összetett alkalmazásunk van több párhuzamos kéréssel, akkor az alkalmazás betöltésének különböző részeit véletlenszerű sorrendben látjuk. . Az alkalmazások természetesebb viselkedése az, hogy felülről lefelé jeleníti meg a dolgokat.

Rendering-as-you-fetch

Render-a-you-fetch megközelítés lehetővé teszi, hogy a hálózati kérés elindítása után azonnal megkezdjük a komponensünk renderelését, és nagyjából a hálózati kérés elindítása után azonnal megkezdjük a renderelést.

Suspense az adatlekéréshez

A Suspense használatával nem várjuk meg a választ, mielőtt elkezdjük a renderelést, és a példánk teljes blokkolási idejét (TBT) 106 ms-ról 56 ms-ra csökkentjük.

Feszültség

A React alapvető csapata egyidejű funkciókkal, amelyek megkönnyítik az adatok lekérését a Reactban. Feszültség ezek közé tartozik, és célja, hogy egyszerűsítse a terhelési állapotok kezelését a React komponensekben. Ez egy funkció a React alkalmazás aszinkron műveleteinek kezelésére, és lehetővé teszi a használatát is <Suspense> deklaratívan „várni” bármi másra, beleértve az adatokat is, és többé nem kell megvárnia az összes JavaScript betöltését, hogy elkezdje hidratálni az oldal egyes részeit.

Először is elindítjuk a hálózati kérést, mielőtt bármely összetevőt az első vonalon megjelenítenénk. Főleg App komponenst, mindkettőt becsomagoljuk  Category és a Cards, Main alkatrészek külön-külön Suspense alkatrészek a visszaeséseikkel.

ReactDataFetchSuspense

SuspenseCall

Amikor App először csatlakozik, megpróbálja renderelni Category és ez kiváltja a resourseCategories.read() vonal. Ha az adatok még nem állnak készen (azaz a kérés nincs megoldva), akkor a rendszer visszaküldi a Suspense-nek, amely ezután <p>Loading…</p>. Ugyanez történik a Cards és a Main


import React, { Suspense } from 'react';

const App = () => {
  return (
    <main>
      <Suspense fallback={<p>Loading.....</p>}>
        <Cards />
      </Suspense>
      <div>
        <Suspense fallback={<p>Loading.....</p>}>
          <Category />
        </Suspense>
      </div>
    </main>
  );
};

export default App;

Suspense ez nem egy új felület az adatok lekéréséhez, mivel ez a feladat továbbra is olyan könyvtárakra van delegálva, mint a fetch vagy az Axios, és Suspense Az igazi feladat az, hogy csak annyit mondunk, hogy „betöltés közben mutasd meg ezt a kódot, és mutasd meg, ha kész”, semmi több.

Törölje le a lekérés logikáját wrapPromise.js

Szükségünk van a tördelési lekérés logikájára is, hogy kivételt dobjunk, amikor az összetevőink betöltik az adatokat, vagy az nem sikerült, de egyszerűen visszaadjuk a választ, ha Promise sikeresen megoldódik, és ha még függőben van, visszavonja az ígéretet.




function wrapPromise(promise) {
  let status = 'pending';
  let response;

  const suspender = promise.then(
    res => {
      status = 'success';
      response = res.objects;
    },
    err => {
      status = 'error';
      response = err;
    },
  );

  const handler = {
    pending: () => {
      throw suspender;
    },
    error: () => {
      throw response;
    },
    default: () => response,
  };

  const read = () => {
    const result = handler[status] ? handler[status]() :
    handler.default();
    return result;
  };

  return { read };
}

export default wrapPromise;

Végén a wrapPromise függvény ellenőrzi ígéretünk állapotát, majd visszaad egy objektumot, amely tartalmazza a read metódusként működnek, és ez az, amivel a React komponenseink kölcsönhatásba lépnek az ígéret értékének lekéréséhez.

Most be kell csomagolnunk a kozmikus hívási függvényeket wrapPromise:



export function fetchDataByType(objectType = 'categories') {
  const params = {
    query: {
      type: objectType,
    },
    props: 'title,slug,id,metadata',
    sort: '-created_at',
  };

  const data = bucket.getObjects(params);
  return wrapPromise(data);
}

A fenti csak egy absztrakció a kozmikus letöltési függvényekhez Suspense és hozd el egyszer.

Olvassa el az adatokat az összetevőben

Ha minden a dolgok lekérési oldalán van, szeretnénk használni az összetevőnkban. Tehát mi történik, amikor az összetevőt nevezzük a read() függvény elkezd kivételeket dobni, amíg teljesen fel nem oldódik, és amikor ez megtörténik, folytatja a kód többi részével, esetünkben annak megjelenítésével.


import React from 'react';
import { fetchDataByType } from '../../cosmic.js';
import styles from '../../styles/Collection.module.scss';

const resourseCategories = fetchDataByType();

const Category = () => {
  const categories = resourseCategories.read();

  const renderCategories = categories?.map((info) => (
    <div key={info?.id} className={styles.user}>
      <div className={styles.avatar}>
        <img
          className={styles.image}
          src={info?.metadata?.image?.imgix_url}
          alt="Avatar"
        />
      </div>
      <div className={styles.description}>
        <div className={styles.name}>{info?.metadata?.title}</div>
        <div
          className={styles.money}
          dangerouslySetInnerHTML={{ __html: info?.content }}
        />
      </div>
    </div>
  ));

  return <div className={styles.collections}>{renderCategories}</div>;
};

export default Category;

A szülő komponens

Suspense hozzáférést biztosít a Reactnak az alkalmazásainkban lévő függőben lévő állapotokhoz, és ezért tudja a React, hogy hálózati hívás történik, ez lehetővé teszi számunkra, hogy várakozás közben deklaratívan rendereljünk egy tartalék komponenst.


import React, { Suspense } from 'react';
import Cards from './components/Cards';
import Category from './components/Category';
import Main from './components/Main';
import styles from './styles/Collection.module.scss';

const App = () => {
  return (
    <div className={styles.wrapper}>
      <div className={cn('section-pb', styles.section)}>
        <div className={cn('container', styles.container)}>
          <div className={styles.row}>
            <Suspense fallback={<p>Loading.....</p>}>
              <Main />
              <Cards />
            </Suspense>
          </div>
          <div className={styles.sidebar}>
            <div className={styles.info}>
              Collections
              <span className={styles.smile} role="img" aria-label="fire">
                🔥
              </span>
            </div>
            <Suspense fallback={<p>Loading.....</p>}>
              <Category />
            </Suspense>
          </div>
        </div>
      </div>
    </div>
  );
};

export default App;

Következtetés

Most, a Suspense, az alkalmazást kis, önálló egységekre bonthatja, amelyek az alkalmazás többi része nélkül önmagukban is renderelhetők, így a tartalom még sokkal gyorsabban is elérhetővé válik a felhasználó számára, mint korábban. Összehasonlítás céljából megvizsgáltuk a különféle adatlekérési megközelítéseket.

Próbálja ki saját projektjében, és adja meg visszajelzését. El lehet kezdeni Kozmikus egy gyors CMS-hez, amellyel tesztelheti az adatlekérést Suspense webhelyekhez és alkalmazásokhoz.

Időbélyeg:

Még több Codementor React Fact