Polymorphe Komponenten mit React und TypeScript erstellen
Das Hinzufügen von Polymorphismus zu Ihren React-Komponenten macht sie vielseitiger, da die Verbraucher das Element definieren können, das in die DOM.
Beim Erstellen dieser Komponenten sind wichtige Schritte zu befolgen, also fangen wir an!
Warum brauchen wir polymorphe Komponenten?
Sie haben vielleicht bemerkt, dass einige Komponenten in einigen Bibliotheken wie ( Material UI oder Chakra UIas ) die Option haben, eine oder elementTypeRequisite zuzulassen . Dies ist wichtig für die Anpassung, aber auch zur Verbesserung der Zugänglichkeit, indem es uns ermöglicht wird, semantische HTML-Elemente beim Rendern unserer Komponenten zu verwenden.
Hinzufügen einer asRequisite zu einer React-Komponente
Mal sehen, wie wir etwas Ähnliches wie diese Bibliotheken implementieren könnten – wir beginnen mit einer einfachen TextReact-Komponente.
const Text = ({ as, children, ...rest }) => {
const Component = as || "span";
return <Component {...rest}>{children}</Component>;
};
export default function App() {
return <Text>Text goes here</Text>; // Will render a span by default
}
<Text as="main">Text goes here</Text>;
<Text as="p">Text goes here</Text>;
<Text as="section">Text goes here</Text>;
<Text as="a" href="www.example.com">Text goes here</Text>
Klappt wunderbar! Ach, aber warte…
<Text as="p" href="www.example.com">
Text goes here
</Text>
Hier kommt TypeScript
Hier kommt unser bester Freund TypeScript ins Spiel.
Wir müssen sicherstellen, dass die TextKomponenten-Requisiten stark typisiert sind, damit sie während des Entwicklungsprozesses statisch überprüft werden können.
Der Plan ist, unserem Prop zu erlauben as, jedes gültige HTML-Element zu akzeptieren und dann irgendwie zu bestimmen, welche HTML-Attribute basierend auf demselben Element gültig sind (zB asollte ein Tag das hrefAttribut zulassen).
Erstellen unserer Typen
Beginnen wir mit der Einrichtung eines Typs für die asRequisite.
import { ElementType } from "react";
type AsProp<T extends ElementType> = {
/**
* The HTML element used for the root node.
*/
as?: T;
};
Unser Typ Tist auf Typen beschränkt, die ElementTypevon React ausgehen, dh alle gültigen HTML-Elemente.
import { ComponentPropsWithoutRef } from "react";
ComponentPropsWithoutRef<T>
Omit<ComponentPropsWithoutRef<T>, keyof Props<T>>
Props<T> & Omit<ComponentPropsWithoutRef<T>, keyof Props<T>>
Unsere kombinierten Typen sollten in etwa so aussehen:
type TextProps<T extends ElementType> = PropsWithChildren<AsProp<T>> &
Omit<ComponentPropsWithoutRef<T>, keyof AsProp<T>>;
Endlich TextPropsalles was wir brauchen Text! Lassen Sie uns alles zusammenfügen und den Typ zu unserer TextKomponente hinzufügen:
import {
ElementType,
ComponentPropsWithoutRef,
PropsWithChildren
} from "react";
type AsProp<T extends ElementType> = {
/**
* The HTML element used for the root node.
*/
as?: T;
};
type TextProps<T extends ElementType> = PropsWithChildren<AsProp<T>> &
Omit<ComponentPropsWithoutRef<T>, keyof AsProp<T>>;
const Text = <T extends ElementType = "span">({
as,
children,
...rest
}: TextProps<T>) => {
const Component = as || "span";
return <Component {...rest}>{children}</Component>;
};
Das Beste an unserem Setup ist, dass jetzt ...restauch stark typisiert wird.
Das sollte also funktionieren:
<Text as="a" href="www.google.com">
Text goes here
</Text>
<Text as="main" href="www.google.com">
Text goes here
</Text>

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































