React 18 Suspense mengambil data dari CMS PlatoBlockchain Data Intelligence tanpa kepala. Pencarian Vertikal. Ai.

React 18 Suspense mengambil data dari CMS tanpa kepala

Untuk memberikan pengalaman pengguna situs web yang luar biasa, kami perlu mengoptimalkan waktu buka halaman awal pertama dan respons halaman terhadap interaksi. Semakin cepat halaman Anda merespons masukan pengguna – semakin baik.

Bereaksi 18 dirancang untuk membantu meningkatkan interaktivitas dengan fitur seperti hidrasi selektif dengan Suspense untuk membuat hidrasi non-blocking dan memberi kami lebih banyak transparansi tentang bagaimana kami arsitektur pilihan akan memengaruhi UX dan kinerja aplikasi kami. React 18 membuat peningkatan kinerja utama dan menambahkan dukungan untuk Suspense pada rendering sisi server (SSR) yang memungkinkan penyajian bagian aplikasi secara asinkron, Anda dapat membungkus bagian aplikasi yang lambat dalam komponen Suspense, memberi tahu React untuk menunda pemuatan komponen yang lambat.

Bereaksi 18 baru-baru ini dirilis dengan fitur yang dirancang untuk membantu meningkatkan interaktivitas. Fitur seperti hidrasi selektif dengan Suspense untuk membuat hidrasi non-blocking dan memberi kami lebih banyak transparansi tentang bagaimana kami arsitektur pilihan akan memengaruhi UX dan kinerja aplikasi kami. React 18 menambahkan dukungan untuk Suspense pada rendering sisi server (SSR) yang memungkinkan penyajian bagian aplikasi secara asinkron, Anda dapat membungkus bagian aplikasi yang lambat dalam komponen Suspense, memberi tahu React untuk menunda pemuatan komponen yang lambat.

Render sisi server memungkinkan Anda menghasilkan HTML dari komponen React di server, dan mengirimkan HTML itu ke pengguna Anda. SSR memungkinkan pengguna Anda melihat konten halaman sebelum bundel JavaScript Anda dimuat dan dijalankan, setelah itu kode JavaScript dimuat dan digabungkan dengan HTML, melampirkan pengendali peristiwa – yang hidrasi. Tidak seperti streaming HTML tradisional, itu tidak harus terjadi dalam urutan top-down.

React-18-Suspense.jpeg
Dengan Suspense, Anda dapat memberi tahu React untuk mengirim HTML untuk komponen lain terlebih dahulu bersama dengan HTML untuk placeholder, seperti pemintal pemuatan. Ini secara signifikan meningkatkan pengalaman pengguna dan latensi yang dirasakan pengguna.

Ada dua fitur SSR utama di React 18 dibuka oleh Suspense:

  • Streaming HTML di server.
  • Hidrasi Selektif pada klien.

Mari kita jelajahi Pendekatan pengambilan data React dengan useEffect dan Suspense coba bandingkan solusi praktis pengambilan data backend, dalam kasus kami, kami memilih CMS tanpa kepala yang cepat dan intuitif Kosmik. Contoh kode kami, Anda dapat memeriksa dengan tautan TumpukanBlitz.
React18

Integrasi Cosmic Headless CMS

Untuk mengambil data kami menggunakan CMS tanpa kepala kosmik adalah sistem manajemen konten (CMS) back-end only adalah sistem manajemen konten back-end-only (CMS), yang dibangun dari bawah ke atas sebagai repositori konten yang membuat konten dapat diakses. Untuk mengintegrasikan dan mendapatkan nilai dari Cosmic, kita perlu menginstal modul Cosmic di proyek Anda.

npm i cosmicjs

yarn add cosmicjs

Kemudian buat akun kosmik gratis dan pergi ke Dasbor Kosmik Your Bucket > Settings > API Access dan temukan siput Bucket dan kunci baca API Anda dan tambahkan untuk membuat fungsi pengambilan Cosmic fetchDataByType minta ke ember Cosmic Anda dan ambil konten Kategori yang dibuat oleh Permintaan kosmik mengetik 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 };
  }
}

Cosmic juga menyediakan fitur pemodelan konten yang kuat yang memungkinkan Anda membuat segala jenis konten super cepat dan penerbitan multi-saluran, untuk mewujudkan buat sekali dan publikasikan di mana saja.

Ambil-di-render

Pendekatan Fetch-on-render permintaan jaringan dipicu dalam komponen itu sendiri setelah pemasangan, permintaan tidak dipicu hingga komponen dirender. Jika Anda tidak menulis fungsi pembersihan yang mengabaikan respons basi, Anda akan melihat a kondisi balapan (dalam React) bug ketika dua permintaan data yang sedikit berbeda telah dibuat, dan aplikasi menampilkan hasil yang berbeda tergantung pada permintaan mana yang diselesaikan terlebih dahulu. Sebenarnya pada React 18, jika Anda mengaktifkan StrictMode di aplikasi Anda, dalam mode pengembangan Anda akan mengetahui bahwa menggunakan useEffect akan dipanggil dua kali, karena sekarang React akan memasang komponen Anda, turun, dan kemudian memasangnya lagi, untuk memeriksa apakah kode Anda bekerja dengan benar.

Mari perbaiki kondisi balapan pengambilan data dengan memanfaatkan useEffect fungsi pembersihan. Jika kita baik-baik saja dengan membuat beberapa permintaan, tetapi hanya merender hasil terakhir, kita dapat menggunakan flag boolean 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;

Selain itu, jika komponen merender beberapa kali (seperti biasanya), efek sebelumnya dibersihkan sebelum menjalankan efek berikutnya.

Dalam hal ini, kami masih memiliki kondisi balapan dalam arti bahwa beberapa permintaan ke Cosmic akan diterbangkan, tetapi hanya hasil dari yang terakhir yang akan digunakan.

AmbilDenganMenggunakanEfek

gunakanEfek

Juga sebagai Dan Abramov menjelaskan, Ambil-di-render menyediakan navigasi lambat antar layar. Jika Anda memiliki komponen induk dan anak keduanya melakukan pengambilan useEffects, maka komponen anak bahkan tidak dapat mulai mengambil sampai komponen induk selesai mengambil. Jenis masalah kinerja ini sangat umum di aplikasi satu halaman dan menyebabkan lebih banyak kelambatan daripada "re-rendering yang berlebihan" dan jika kita memiliki aplikasi yang kompleks dengan beberapa permintaan paralel, kita akan melihat bagian yang berbeda dari pemuatan aplikasi secara acak. . Perilaku yang lebih alami untuk suatu aplikasi adalah merender sesuatu dari atas ke bawah.

Render saat Anda mengambil

Pendekatan render-as-you-fetch memungkinkan kami mulai merender komponen kami segera setelah memicu permintaan jaringan dan kami mulai merender segera setelah memulai permintaan jaringan.

Ketegangan untuk Pengambilan Data

Dengan Suspense, kami tidak menunggu respons kembali sebelum kami mulai merender dan mengurangi Total Blocking Time (TBT) dari contoh kami dari 106 md menjadi 56 md.

Ketegangan

Kumpulan fitur bersama tim inti React untuk membuat pengambilan data di React lebih mudah. Ketegangan adalah salah satunya, dan ini bertujuan untuk menyederhanakan pengelolaan status pemuatan di komponen React. Ini adalah fitur untuk mengelola operasi asinkron di aplikasi React dan memungkinkan Anda juga menggunakan <Suspense> untuk secara deklaratif "menunggu" untuk hal lain, termasuk data, dan tidak lagi harus menunggu semua JavaScript dimuat untuk mulai menghidrasi bagian halaman.

Pertama, kami memicu permintaan jaringan sebelum merender komponen apa pun di baris pertama. Utamanya App komponen, kami membungkus keduanya  Category dan Cards, Main komponen terpisah Suspense komponen dengan fallback-nya.

ReactDataFetchSuspense

Panggilan Ketegangan

Ketika App mount untuk pertama kalinya, ia mencoba untuk membuat Category dan ini memicu resourseCategories.read() garis. Jika data belum siap (yaitu, permintaan belum diselesaikan), itu dikomunikasikan kembali ke Suspense, yang kemudian di-render <p>Loading…</p>. Hal yang sama terjadi pada Cards dan 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 itu bukan antarmuka baru untuk mengambil data, karena pekerjaan itu masih didelegasikan ke perpustakaan seperti fetch atau Axios, dan Suspense pekerjaan sebenarnya adalah hanya mengatakan "tunjukkan kode ini saat sedang memuat, dan tunjukkan bahwa ketika selesai", tidak lebih dari itu.

Bungkus logika pengambilan Anda wrapPromise.js

Kita juga membutuhkan logika pengambilan bungkus, untuk melempar pengecualian ketika komponen kita memuat data atau gagal, tetapi kemudian cukup mengembalikan respons setelah Promise diselesaikan dengan sukses dan jika masih tertunda, ia mengembalikan Janji.




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;

Di akhir wrapPromise fungsi akan memeriksa status janji kami, lalu mengembalikan objek yang berisi read berfungsi sebagai metode, dan inilah komponen React kita yang akan berinteraksi untuk mengambil nilai dari Promise.

Sekarang kita perlu membungkus fungsi panggilan Cosmic untuk 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);
}

Di atas hanyalah abstraksi untuk fungsi pengambilan Cosmic dengan Suspense dan ambil satu kali.

Baca data di komponen

Setelah semuanya terbungkus di sisi pengambilan, kami ingin menggunakannya di komponen kami. Jadi apa yang terjadi ketika kita memanggil komponen, the read() function akan mulai melempar pengecualian hingga diselesaikan sepenuhnya, dan ketika itu terjadi, ia akan melanjutkan dengan sisa kode, dalam kasus kami untuk merendernya.


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;

Komponen induk

Suspense memberikan React akses ke status tertunda di aplikasi kita dan itulah mengapa React mengetahui bahwa panggilan jaringan sedang terjadi, ini memungkinkan kita untuk merender komponen fallback secara deklaratif sambil menunggu.


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;

Kesimpulan

Sekarang, dengan Suspense, Anda dapat memecah aplikasi menjadi unit-unit kecil yang berdiri sendiri yang dapat dirender sendiri tanpa aplikasi lainnya, sehingga konten dapat tersedia bagi pengguna jauh lebih cepat dari sebelumnya. Kami menjelajahi berbagai pendekatan pengambilan data untuk perbandingan.

Cobalah dalam proyek Anda sendiri dan beri kami umpan balik Anda. Anda dapat memulai dengan Kosmik untuk CMS cepat untuk menguji pengambilan data dengan Suspense untuk situs web dan aplikasi.

Stempel Waktu:

Lebih dari Fakta Reaksi Codementor