Polymorphe Components mit der 'as'-Prop
Typisieren Sie die 'as'-Prop, damit ein Button als oder gerendert wird und dabei die korrekten Prop-Typen erhält.
Polymorphe Components mit der 'as'-Prop ist eine kostenlose React Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des React Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der React Academy-Kurs umfasst insgesamt 4 Lektionen.
Was ist eine polymorphe Komponente?
Eine polymorphe Komponente wird abhängig von einer as-Prop als unterschiedliche HTML-Elemente oder Komponenten gerendert – z. B. eine Button-Komponente, die als <a> oder <button> gerendert wird und dabei die korrekten TypeScript-Typen beibehält.
Einfacher as-Prop (ohne TypeScript)
Eine einfache polymorphe Implementierung ohne Generics – sie verliert die Typsicherheit, veranschaulicht aber das Konzept.
function Box({ as: Tag = 'div', children, ...props }) {
return <Tag {...props}>{children}</Tag>;
}
// Usage:
<Box as="section" className="hero">...</Box>
<Box as="article">...</Box>Typisierter as-Prop mit Generics
Fügen Sie einen generischen Typparameter hinzu, um die korrekten Props für das Element abzuleiten, als das as gerendert wird.
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} />;
}Mit ref-Unterstützung
Fügen Sie Unterstützung für forwardRef hinzu und erhalten Sie dabei die polymorphe Typisierung.
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} />;
}
);TypeScript-Inferenz in Aktion
Wenn Sie as='a' festlegen, weiß TypeScript, dass die Komponente ankerspezifische Props wie href und target akzeptiert, aber keine buttonspezifischen Props wie 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 propUm benutzerdefinierte Props erweitern
Fügen Sie komponentenspezifische Props zur polymorphen Basis hinzu, indem Sie sie in die Typdefinition einfügen.
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}
/>
);
}Praxisbeispiel: Link, der als RouterLink gerendert wird
Ein Button, der als Link von React Router gerendert wird, wenn to angegeben ist, und andernfalls als einfacher Button.
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} />;
}Text-Komponente für ein Designsystem
Eine polymorphe Text-Komponente, die standardmäßig als <p> gerendert wird, aber auch als h1–h6, span oder label gerendert werden kann.
<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'Einschränkungen für den as-Prop
Verwenden Sie extends React.ElementType, um sowohl Zeichenfolgen für HTML-Elemente ('div', 'a') als auch React-Komponenten zu akzeptieren.
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 }} />Häufige Fallstricke vermeiden
Verteilen Sie die as-Prop nicht auf das Element (sie ist kein gültiges HTML-Attribut). Destrukturieren Sie sie immer, bevor Sie die übrigen Props verteilen.
// 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
}Performance-Aspekt
Polymorphe Komponenten haben einen minimalen Performance-Overhead – die as-Prop ist lediglich eine Variable, die eine Elementtyp-Zeichenfolge oder eine Komponentenreferenz enthält.
Kurzer Test
Warum sollten Sie die as-Prop destrukturieren, bevor Sie die übrigen Props auf das Element einer polymorphen Komponente verteilen?
Zusammenfassung
Polymorphe Komponenten verwenden eine generische as?: E extends React.ElementType-Prop, um als beliebiges Element gerendert zu werden und dabei die korrekten TypeScript-Props beizubehalten. Destrukturieren Sie as, bevor Sie die übrigen Props verteilen. Verwenden Sie React.ComponentPropsWithoutRef, um alle elementspezifischen Attribute in den Typ aufzunehmen.
Häufig gestellte Fragen
Ist die Lektion „Polymorphe Components mit der 'as'-Prop“ kostenlos?
Ja — der vollständige Text von „Polymorphe Components mit der 'as'-Prop“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des React Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der React Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Polymorphe Components mit der 'as'-Prop“?
Typisieren Sie die 'as'-Prop, damit ein Button als oder gerendert wird und dabei die korrekten Prop-Typen erhält. Du übst React Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um React Academy zu starten?
Keine Vorkenntnisse erforderlich. React Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Polymorphe Components mit der 'as'-Prop“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser React Academy-Lektion Code schreiben und ausführen?
Ja. Jede React Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Discriminated Unions für Component-Varianten
- Bedingte und gemappte Types in React
- Polymorphe Components mit der 'as'-Prop
- Typsichere Formulare und API-Response-Verträge