Erstellen von Komponenten
Vorbereitung
In den meisten Fällen sollten Jutro-Komponenten Ihren Anforderungen entsprechen. Eventuell möchten Sie jedoch Komponenten erstellen, um Ihren Code zu organisieren und Ihre Seiten zu erstellen. In folgenden Fällen erstellen Sie eigene Komponenten:
- Sie möchten den Status oder die komplexe Konfiguration einer Jutro-Komponente verwalten.
- Sie möchten Ihre benutzerdefinierte Logik mit einer Komponente umschließen.
- Sie möchten mehrere Komponenten in einem Widget gruppieren, das eine bestimmte Anforderung erfüllt. Insbesondere, wenn dieses Widget an mehreren Stellen wiederverwendet werden soll.
- Sie fügen eine Seite in Ihrer Anwendung ein. Es ist sinnvoll, die Seite in einer React-Komponente zu kapseln und im Grundriss zu verwenden.
Ihre benutzerdefinierte Komponente kann wie folgt aussehen:
Erweiterte Komponenten
Um eine Jutro-Komponente zu erweitern, können Sie sie mit einer eigenen Komponente umschließen. Damit können Sie Standardeigenschaften oder Ereignis-Handler festlegen. Diese Komponente erbt Lokalisierungs-, Zugänglichkeits- und andere relevante Funktionen.
Sie können beispielsweise das Feld FavoriteBook mit der Beschriftung „Favorite Book“ erstellen, für das immer ein spezifischer Stil angewendet wird.
import { TextInput } from '@jutro/components';
import messages from './FavoriteBook.messages.js';
import styles from './FavoriteBook.module.scss';
. . .
const FavoriteBook = () => {
return (
<TextInput
label="Favorite Book"
placeholder="What is your favorite book?"
classname="favoritebook"
/>
);
};
Zusammengesetzte Komponenten
Sie können neue Komponenten erstellen, indem Sie vorhandene Jutro-Komponenten, erweiterte und benutzerdefinierte Komponenten gruppieren. Diese zusammengesetzten Komponenten erben alle relevanten Funktionen der verwendeten Jutro-Komponenten.
Erstellen Sie z. B. eine benutzerdefinierte Komponente ControlCenter mit Jutro-Komponenten wie Card, NumberValuenumber, Grid oder Icon und mehreren benutzerdefinierten Eigenschaften und dem Lokalisierungsmechanismus, um spezifische Kundeninformationen anzuzeigen.
import { Card, NumberValue, Icon } from '@jutro/components';
import { Grid, GridItem } from '@jutro/layout';
import messages from './ControlCenter.messages.js';
export const ControlCenter = (props) => {
const icon =
props.daysSince < 7
? 'gw-error'
: props < 30
? 'gw-warning'
: 'gw-check-circle';
const style =
props.daysSince < 7
? { color: 'red' }
: props.daysSince < 30
? { color: 'orange' }
: { color: 'green' };
return (
<Card
title={messages.heading}
style={style}>
<Grid columns={['1fr', '1fr']}>
<GridItem>
<Icon icon={icon} />
</GridItem>
<GridItem>
<NumberValue
id="daysSince"
value={props.daysSince}
suffix={messages.dayssince}
/>
</GridItem>
</Grid>
</Card>
);
};
Best Practices für die Erstellung einer neuen Komponente
Befolgen Sie beim Erstellen neuer Komponenten folgende allgemeine Richtlinien:
-
Verwenden Sie in den Komponenten keinen fest codierten Text. Speichern Sie Übersetzungszeichenfolgen in
ComponentName.messages.jsund importieren Sie sie wie folgt:import messages from './ComponentName.messages.js'; -
Fügen Sie Stile in der Datei
ComponentName.module.scsshinzu und importieren Sie sie wie folgt:import styles from './ComponentName.module.scss'; -
Aus folgenden Gründen wird empfohlen, Funktionskomponenten anstelle von Klassenkomponenten zu verwenden:
-
Funktionskomponenten lassen sich erheblich einfacher lesen und testen, da es sich um einfache JavaScript-Funktionen ohne Status und Lebenszyklus-Hooks handelt.
-
Dadurch wird weniger Code verwendet.
-
Sie helfen Ihnen bei der Anwendung von Best Practices. Es wird einfacher, Container und Präsentationskomponenten zu trennen, da Sie sich eingehender mit dem Status der Komponente befassen müssen, wenn Sie keinen Zugriff auf
setState()in der Komponente haben.
Klicken Sie hier, um weitere Informationen zu Funktionskomponenten zu erhalten.
-
Ordnerstruktur erstellen
Erstellen Sie unter src/Components ein Verzeichnis für die Komponente, z. B CustomInput, und fügen Sie die folgenden Dateien hinzu:
src/components/CustomInput/CustomInput.test.tsxsrc/components/CustomInput/CustomInput.tsxsrc/components/CustomInput/CustomInput.messages.tssrc/components/CustomInput/CustomInput.module.scss
Durch Einhaltung dieser Namenskonvention lassen sich künftige Aktualisierungen einfacher durchführen.
Komponente erstellen
- Erstellen Sie im Verzeichnis
CustomInputdie Datei<componentName>.tsx, in diesem Beispiel./CustomInput.tsx. - Der Code der Komponente
CustomInputmuss Folgendes angeben:- Erwartete Eigenschaften (
PropTypes) und deren zugehörige Werte - Statusverwaltungsfunktionen unter Verwendung der Funktionen
writeValueundreadValue.writeValuemuss den Wert der KomponentetestInputübernehmen, den Status der Komponente zurücksetzen und den Wert vontestInputan die KomponentetestOutputausgeben.
- Erwartete Eigenschaften (
import React, { useContext } from 'react';
import { TranslatorContext } from '@jutro/locale';
import styles from './CustomInput.module.scss';
import messages from './CustomInput.messages.ts';
type CustomInputProps = {
title?: string,
};
export const CustomInput: React.FC<CustomInputProps> = ({ title }) => {
const translator = useContext(TranslatorContext);
return (
<div
className={styles.customInput}
title={title}>
{translator(messages.label)}
</div>
);
};
Meldungsdatei erstellen (optional)
Wie im Abschnitt Best Practices angegeben, sollte die Komponente keinen fest codierten Text enthalten. Sie müssen also eventuell die Meldungsdatei erstellen, um die Umwandlungszeichenfolgen zu speichern:
import { defineMessages } from 'react-intl';
export default defineMessages({
label: {
id: 'jutro-app.components.CustomInput.label',
defaultMessage: 'custom inputLabel',
},
});
Weitere Informationen finden Sie im Abschnitt Internationalisierung und Lokalisierung.
<ComponentName>.messages.js angegeben werden.Stylesheet-Datei erstellen (optional)
Bei Bedarf können Sie zusätzliche Stile in der Datei ./CustomInput.module.scss definieren.
<ComponentName>.module.scss angegeben werden.Komponente auf Barrierefreiheit testen
Achten Sie darauf, dass die Komponente zumindest die grundlegenden Anforderungen für die Zugänglichkeit erfüllt:
- Verfügbarkeit für Screenreader
- Navigation über Tastatur möglich
- Angemessener Kontrast
Weitere Informationen finden Sie auf unserer Seite über Barrierefreiheit.
Tests für eigene Komponenten schreiben
Damit Ihre Komponente lange Zeit funktionsfähig bleibt, sind vollständige und gründliche Tests unerlässlich. Weitere Informationen dazu finden Sie im umfassenden Abschnitt zu Tests.
Hier ein Beispieltest für die erstellte Komponente:
import React from 'react';
import {
render,
screen,
getTranslation,
checkA11yViolations,
} from '@jutro/test';
import messages from './CustomInput.messages';
import { CustomInput } from './CustomInput';
describe('CustomInput', () => {
it('renders default component', () => {
const sampleTitle = 'sample';
render(<CustomInput title={sampleTitle} />);
expect(screen.getByTitle('sample')).toBeInTheDocument();
});
it('renders with custom prop value', () => {
const newTitle = 'newTitle';
render(<CustomInput title={newTitle} />);
expect(screen.getByTitle(newTitle)).toBeInTheDocument();
});
it('renders with css class', () => {
const sampleTitle = 'sample';
render(<CustomInput title={sampleTitle} />);
expect(screen.getByTitle('sample')).toHaveClass('customInput');
});
it('renders with translation', () => {
render(<CustomInput />);
expect(
screen.getByText(getTranslation(messages.label))
).toBeInTheDocument();
});
it('has no a11y violations', async () => {
await checkA11yViolations(<CustomInput />);
});
});
Komponenten in einem neuen Paket
Beim Erstellen von Komponenten, die vollständig eigenständig und wiederverwendbar sein müssen, empfiehlt es sich, einen Abhängigkeitsbaum in einer package.json-Datei auf Komponentenebene zu erstellen. Anschließend erstellen Sie eine JavaScript-Datei, die als Einstiegspunkt in Ihr Modul dient, die alle Unterkomponenten importiert und erneut exportiert, damit sie wiederverwendet werden können.
Für eine MyCustomComponent-Komponente gehen Sie wie folgt vor:
-
Erstellen Sie einen neuen Paketordner mit dem Namen
CustomInput. -
Erstellen Sie wie folgt die Datei
index.jszum Exportieren der Unterkomponenten vonCustomComponent:import SubComponent1 from './SubComponent1';
import SubComponent2 from './SubComponent2';
import SubComponent3 from './SubComponent3';
export { SubComponent1, SubComponent2, SubComponent3 }; -
Definieren Sie die Datei
package.jsonmit Abhängigkeiten.{
"name": "my-custom-component-module",
"description": "Description for my-component",
"main": "index.js",
"version": "1.0.1-32745cd39da0",
"author": "Your Name",
"private": true,
"dependencies": {
// other component modules are re-used by MyComponent
"self-contained-component-module": "someVersion",
"another-self-contained-component-module": "someVersion"
},
"peerDependencies": {
// dependencies such as React, Lodash are set as peer dependencies
"react": "18.x",
"prop-types": "15.x",
"react-intl": "2.9.x",
"lodash": "4.x",
"classnames": "^2.x"
}
} -
Fügen Sie den Modulverweis (my-component-module) in der Datei
package.jsonder Anwendung als Abhängigkeit hinzu. -
Verwenden Sie das Modul durch Importieren von Unterkomponenten aus dem Paket.
import { SubComponent1, SubComponent3 } from 'my-custom-component-module';
Diese Komponente und ihre Unterkomponenten können in der Anwendung uneingeschränkt wiederverwendet werden.