Wiederverwendbare Komponenten in React
Wiederverwendbare Komponenten in React
Schaue dir die Suchkomponente genauer an. Das Label-Element hat den Text “Search: “. Das id/htmlFor-Attribut
hat die Kennung search
. Der Wert heißt search
und der Callback-Handler hat den Namen onSearch
. Du siehst: Die Komponente ist in hohem Maße mit der Suchfunktion gekoppelt. Das macht sie für den Rest der Anwendung und für nichtsuchbezogene Aufgaben wertlos. Außerdem besteht die Gefahr, dass Fehler auftreten, wenn zwei dieser Suchkomponenten nebeneinander gerendert werden, da die Kombination aus htmlFor
und id
dupliziert wird. Im Übrigen wird der Fokus nicht immer korrekt gesetzt, wenn der Benutzer auf eines der Labels klickt.
Probiere es aus, um dir dies praktisch anzusehen:
const App = () => {
...
return (
<div>
<h1>My Hacker Stories</h1>
<Search search={searchTerm} onSearch={handleSearch} />
<hr />
<List list={searchedStories} />
# start-insert
<Search search={searchTerm} onSearch={handleSearch} />
# end-insert
</div>
);
...
};
Da die Suchkomponente keine tatsächliche “Such”-Funktionalität hat, ist sie leicht verallgemeinerbar. In einer allgemeineren Form wäre sie für den Rest der Anwendung besser wiederverwendbar. Deshalb geben wir der Suchkomponente zusätzlich die Eigenschaften (Props) id
und label
und benennen den Wert, den Callback-Handler und die Komponente um. Wir geben allen einen allgemeineren Namen:
const App = () => {
...
return (
<div>
<h1>My Hacker Stories</h1>
# start-insert
<InputWithLabel
id="search"
label="Search"
# end-insert
value={searchTerm}
# start-insert
onInputChange={handleSearch}
# end-insert
/>
...
</div>
);
};
# start-insert
const InputWithLabel = ({ id, label, value, onInputChange }) => (
# end-insert
<>
# start-insert
<label htmlFor={id}>{label}</label>
# end-insert
<input
# start-insert
id={id}
# end-insert
type="text"
value={value}
# start-insert
onChange={onInputChange}
# end-insert
/>
</>
);
Unsere Komponente ist in Bezug auf die Wiederverwendbarkeit weiterhin verbesserungsfähig. Falls wir ein Eingabefeld für Daten wie eine E-Mail-Adresse (email
) oder eine Telefonnummer (tel
) wünschen, ist es notwendig, dass das Attribut type
des Eingabefelds von außen zugänglich ist:
const InputWithLabel = ({
id,
label,
value,
# start-insert
type = 'text',
# end-insert
onInputChange,
}) => (
<>
<label htmlFor={id}>{label}</label>
<input
id={id}
# start-insert
type={type}
# end-insert
value={value}
onChange={onInputChange}
/>
</>
);
Von der App-Komponente wird keine type
-Eigenschaft (Props) an InputWithLabel übergeben, sodass dies nicht von außen festgelegt ist. Das Eingabefeld übernimmt den Standard-Funktionsparameter, den wir statisch in der Funktionssignatur eingefügt haben.
Mit nur wenigen Änderungen haben wir eine spezialisierte Suchkomponente in eine wiederverwendbarere Komponente verwandelt. Wir haben die Namen verallgemeinert und die API erweitert. So werden alle erforderlichen Informationen von außen bereitgestellt. Wir verwenden die Komponente bisher an keiner anderen Stelle. Ab jetzt wäre dies unkompliziert möglich, weil alle notwendigen Voraussetzungen gegeben sind.
Übungen:
- Begutachte den Quellcode dieses Abschnitts.
- Reflektiere die Änderungen gegenüber dem letzten Abschnitt.
- Lese mehr zum Thema Wiederverwendebare Komponenten in React.
- Ist es dir aufgefallen: Bisher haben wir den Text “Search:” mit einem ”:” verwendet. Welche Möglichkeiten haben wir jetzt mit der wiederverwendbareren Version der Komponente? Würdest du
label="Search:"
als Eigenschaft (Props) an InputWithLabel übergeben oder den Doppelpunkt in InputWithLabel mit<label htmlFor={id}>{label}:</label>
fest codieren? Wir werden diese Frage später im Buch erneut aufgreifen.