Polymorfa komponenter med propen 'as'
Typa propen 'as' så att en Button renderas som eller samtidigt som korrekta prop-typer bevaras.
Polymorfa komponenter med propen 'as' är en gratis lektion i React Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för React Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i React Academy innehåller totalt 4 lektioner.
Vad är en polymorf komponent?
En polymorf komponent renderas som olika HTML-element eller komponenter baserat på en as-prop – till exempel en Button som renderas som <a> eller <button> samtidigt som korrekta TypeScript-typer bevaras.
En enkel as-prop (utan TypeScript)
En grundläggande polymorf implementation utan generics – den förlorar typsäkerheten men visar konceptet.
function Box({ as: Tag = 'div', children, ...props }) {
return <Tag {...props}>{children}</Tag>;
}
// Usage:
<Box as="section" className="hero">...</Box>
<Box as="article">...</Box>Typad as-prop med generics
Lägg till en generisk typparameter för att härleda korrekta props för det element som as renderas som.
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} />;
}Med ref-stöd
Lägg till stöd för forwardRef samtidigt som den polymorfa typningen bevaras.
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-härledning i praktiken
När as='a' anges vet TypeScript att komponenten accepterar ankar- specifika props som href och target, men inte knappspecifika sådana som 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 propUtöka med egna props
Lägg till komponentspecifika props bredvid den polymorfa basen genom att sprida in dem i typdefinitionen.
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}
/>
);
}Praktiskt användningsfall: länk som renderas som RouterLink
En Button som renderas som React Routers Link när to anges, eller som en vanlig knapp i annat fall.
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} />;
}Textkomponent för designsystem
En polymorf Text-komponent som som standard använder <p> men kan renderas som h1–h6, span eller 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'Begränsningar för as-propen
Använd extends React.ElementType för att acceptera både strängar för HTML-element ('div', 'a') och React-komponenter.
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 }} />Undvik vanliga fallgropar
Sprid inte as-propen till elementet (den är inte ett giltigt HTML-attribut). Destrukturera alltid bort den innan återstående props sprids.
// 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
}Prestandaövervägande
Polymorfa komponenter har minimal prestandakostnad – as-propen är bara en variabel som innehåller en sträng för elementtypen eller en komponentreferens.
Snabbkontroll
Varför bör as-propen destruktureras innan återstående props sprids till elementet i en polymorf komponent?
Sammanfattning
Polymorfa komponenter använder en generisk prop, as?: E extends React.ElementType, för att renderas som valfritt element samtidigt som korrekta TypeScript-props bevaras. Destrukturera as innan återstående props sprids. Använd React.ComponentPropsWithoutRef för att inkludera alla elementspecifika attribut i typen.
Lär dig React med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 88
- Lektioner
- 324
Vanliga frågor
Är lektionen ”Polymorfa komponenter med propen 'as'” gratis?
Ja – hela texten till ”Polymorfa komponenter med propen 'as'” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i React Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i React Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Polymorfa komponenter med propen 'as'”?
Typa propen 'as' så att en Button renderas som eller samtidigt som korrekta prop-typer bevaras. Ni övar på React Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig React Academy?
Du behöver inga förkunskaper. Utbildningen i React Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Polymorfa komponenter med propen 'as'”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här React Academy-lektionen?
Ja. Varje React Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Discriminated unions för komponentvarianter
- Villkorliga och mappade typer i React
- Polymorfa komponenter med propen 'as'
- Typsäkra formulär och kontrakt för API-svar