React Academy · Pelajaran

Komponen Polimorfik dengan Prop 'as'

Taip prop 'as' supaya Button dipaparkan sebagai atau sambil mengekalkan jenis prop yang betul.

Pelajaran 3 daripada 413 langkah

Komponen Polimorfik dengan Prop 'as' ialah pelajaran React Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran React Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus React Academy merangkumi sejumlah 4 pelajaran.

Apakah Komponen Polimorfik?

Komponen polimorfik dipaparkan sebagai elemen HTML atau komponen yang berbeza berdasarkan prop as — contohnya, Button yang dipaparkan sebagai <a> atau <button> sambil mengekalkan jenis TypeScript yang betul.

Prop as Ringkas (Tanpa TypeScript)

Pelaksanaan polimorfik asas tanpa generik — kehilangan keselamatan jenis tetapi menunjukkan konsepnya.

function Box({ as: Tag = 'div', children, ...props }) {
  return <Tag {...props}>{children}</Tag>;
}

// Usage:
<Box as="section" className="hero">...</Box>
<Box as="article">...</Box>

Prop as Berjenis dengan Generik

Tambahkan parameter jenis generik untuk membuat inferens prop yang betul bagi mana-mana elemen yang dipaparkan oleh as.

type PolymorphicProps<E extends React.ElementType> = {
  as?: E;
} & Omit<React.ComponentPropsWithoutRef<E>, 'as'>;

function Box<E extends React.ElementType = 'div'>({
  as,
  ...props
}: PolymorphicProps<E>) {
  const Tag = as ?? 'div';
  return <Tag {...props} />;
}

Sokongan ref

Tambahkan sokongan forwardRef sambil mengekalkan penaipan polimorfik.

type PolymorphicRef<E extends React.ElementType> = React.ComponentPropsWithRef<E>['ref'];

type PolymorphicPropsWithRef<E extends React.ElementType, P = {}> = P &
  Omit<React.ComponentPropsWithRef<E>, keyof P> & { as?: E };

const Button = React.forwardRef(
  <E extends React.ElementType = 'button'>(
    { as, ...props }: PolymorphicPropsWithRef<E>,
    ref: PolymorphicRef<E>
  ) => {
    const Tag = as ?? 'button';
    return <Tag ref={ref} {...props} />;
  }
);

Inferens TypeScript dalam Amalan

Apabila anda menetapkan as='a', TypeScript mengetahui bahawa komponen menerima prop khusus sauh seperti href dan target, tetapi bukan prop khusus butang seperti disabled.

// TypeScript allows href because as='a':
<Box as="a" href="https://example.com">Link</Box>

// TypeScript errors if you pass href to a div:
<Box as="div" href="...">Error!</Box> // TS: href is not a valid div prop

Melanjutkan dengan Prop Tersuai

Tambahkan prop khusus komponen bersama-sama asas polimorfik dengan menyebarkannya ke dalam definisi jenis.

type TextProps<E extends React.ElementType> = PolymorphicProps<E> & {
  size?: 'sm' | 'md' | 'lg';
  weight?: 'normal' | 'bold';
};

function Text<E extends React.ElementType = 'p'>({
  as,
  size = 'md',
  weight = 'normal',
  className,
  ...props
}: TextProps<E>) {
  const Tag = as ?? 'p';
  return (
    <Tag
      className={[`text-${size}`, `font-${weight}`, className].filter(Boolean).join(' ')}
      {...props}
    />
  );
}

Kes Penggunaan Sebenar: Pautan yang Dipaparkan sebagai RouterLink

Butang yang dipaparkan sebagai Link React Router apabila to diberikan, atau sebagai butang biasa jika tidak.

import { Link } from 'react-router-dom';

type ButtonProps =
  | { to: string; href?: never } & React.ComponentPropsWithoutRef<typeof Link>
  | { href: string; to?: never } & React.ComponentPropsWithoutRef<'a'>
  | { to?: never; href?: never } & React.ComponentPropsWithoutRef<'button'>;

function Button({ to, href, ...props }: ButtonProps) {
  if (to) return <Link to={to} {...props} />;
  if (href) return <a href={href} {...props} />;
  return <button type="button" {...props} />;
}

Komponen Teks Sistem Reka Bentuk

Komponen polimorfik Text yang secara lalai menggunakan <p> tetapi boleh dipaparkan sebagai h1–h6, span atau label.

<Text as="h1" size="xl">Page Title</Text>
<Text as="span" weight="bold">Inline bold</Text>
<Text as="label" htmlFor="email">Email</Text> // htmlFor is valid because as='label'

Kekangan pada Prop as

Gunakan extends React.ElementType untuk menerima kedua-dua rentetan elemen HTML ('div', 'a') dan komponen React.

function Card<E extends React.ElementType = 'div'>({ as, ...props }: PolymorphicProps<E>) {
  const Tag = as ?? 'div';
  return <Tag {...props} />;
}

// Works with HTML elements:
<Card as="section" aria-label="Products" />
// Works with React components:
<Card as={motion.div} animate={{ opacity: 1 }} />

Mengelakkan Perangkap Biasa

Jangan sebarkan prop as kepada elemen (ia bukan atribut HTML yang sah). Sentiasa ekstrak prop tersebut sebelum menyebarkan prop selebihnya.

// Bad:
function Box({ as: Tag = 'div', ...props }) {
  return <Tag as={...} {...props} />; // 'as' attribute on div is invalid HTML
}

// Good:
function Box({ as: Tag = 'div', ...props }) {
  return <Tag {...props} />; // 'as' is used to pick Tag, not passed to element
}

Pertimbangan Prestasi

Komponen polimorfik mempunyai overhed prestasi yang minimum — prop as hanyalah pemboleh ubah yang menyimpan rentetan jenis elemen atau rujukan komponen.

Semakan Pantas

Mengapakah anda perlu mengekstrak prop as sebelum menyebarkan prop selebihnya kepada elemen dalam komponen polimorfik?

Ringkasan

Komponen polimorfik menggunakan prop generik as?: E extends React.ElementType untuk dipaparkan sebagai sebarang elemen sambil mengekalkan prop TypeScript yang betul. Ekstrak as sebelum menyebarkan prop selebihnya. Gunakan React.ComponentPropsWithoutRef untuk menyertakan semua atribut khusus elemen dalam jenis tersebut.

Percuma untuk bermula

Pelajari React dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
88
Pelajaran
324

Soalan Lazim

Adakah pelajaran “Komponen Polimorfik dengan Prop 'as'” percuma?

Ya — teks penuh “Komponen Polimorfik dengan Prop 'as'” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus React Academy, tingkat taraf kepada CoddyKit PRO. Kursus React Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Komponen Polimorfik dengan Prop 'as'”?

Taip prop 'as' supaya Button dipaparkan sebagai atau sambil mengekalkan jenis prop yang betul. Anda berlatih React Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan React Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran React Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Komponen Polimorfik dengan Prop 'as'” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran React Academy ini?

Ya. Setiap pelajaran React Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Kesatuan Berbeza untuk Varian Komponen
  2. Jenis Bersyarat & Dipetakan dalam React
  3. Komponen Polimorfik dengan Prop 'as'
  4. Borang Selamat Jenis & Kontrak Respons API
← Kembali ke React Academy