Erste Schritte mit Storybook in React

Hast du jemals versucht, alle deine UI-Komponenten an einem Ort in React zu platzieren?

Wenn Sie neu in der Welt von React sind, werden Sie es wahrscheinlich nicht tun.

Was ist damit gemeint?

Siehe die reagieren-schön-dnd Beispiele.

Was Sie in den Beispielen gesehen haben, nennt man Geschichten. Und das Tool, das zum Erstellen von Geschichten verwendet wird, heißt Storybook.

Jetzt haben Sie verstanden, worüber wir in diesem Artikel sprechen werden. Lassen Sie uns ohne Umschweife erkunden.

Was ist Märchenbuch?

Storybook ist eine von der Benutzeroberfläche isolierte Entwicklungsumgebung, die eine Spielwiese für Ihre Komponenten bietet. Wir können mit unseren Komponenten auf verschiedene Arten spielen, ohne unsere Haupt-App auszuführen. Wir können das Storybook in seinem Port mit dem Setup ausführen.

Es ist nicht auf React beschränkt. Wir können Storybook mit den meisten Frontend-Frameworks wie Vue, Angular, Mithril, Marko, Svelte usw. verwenden.

Sie können mehr über das Märchenbuch erfahren hier.

Was ist eine Geschichte?

Eine Story definiert den gerenderten Zustand Ihrer Komponente. Wenn wir eine gemeinsame Komponente nehmen, können wir sie auf unterschiedliche Weise mit Requisiten verwenden. Wir können für jeden dieser Zustände eine Geschichte schreiben.

Nehmen wir an, wir haben eine Button-Komponente.

Eine Schaltfläche kann in verschiedenen Zuständen vorhanden sein, z. B. deaktiviert, geladen, primär, sekundär, klein, groß, mittel usw. Wenn wir alle Zustände auflisten, wird es sehr schwierig, im Tutorial voranzukommen. Ich denke, du verstehst es. Sie werden es mehr bekommen, wenn Sie anfangen, mit dem Märchenbuch zu arbeiten.

Sie können die Geschichten der Schaltfläche in verschiedenen Fällen sehen (Groß, Mittel, Klein).

Storybook in einem Projekt einrichten

Wir werden ein Storybook in einem Reaktionsprojekt einrichten.

Lass uns gehen.

  • Erstellen Sie mit dem folgenden Befehl ein Reaktionsprojekt. Sie können benennen, was Sie möchten.
npx create-react-app storybook-demo
  • Installieren Sie nun das Storybook mit dem folgenden Befehl in Ihrem Projekt.
npx sb init

Wir haben die Einrichtung für das Märchenbuch abgeschlossen.

Das Storybook stellt uns einen eigenen Server zur Verfügung.

Wie starte ich es?

Das Storybook fügt automatisch einen Befehl in unsere Skriptdatei ein. Sie können es in der Datei package.json im Abschnitt scripts überprüfen. Führen Sie vorerst den folgenden Befehl aus, um den Storybook-Server zu starten.

npm run storybook

Storybook startet einen neuen Server mit dem im Abschnitt scripts der Datei package.json angegebenen Port. Das Storybook wird automatisch in unserem Standardbrowser geöffnet (wie der Reaktionsserver).

Sie werden standardmäßig verschiedene Geschichten darin sehen. Sie können sie entfernen, wenn Sie dies nicht möchten, oder sie als Referenz aufbewahren. Wie wir im vorherigen Abschnitt besprochen haben, kann eine Schaltfläche mehrere Zustände haben, Sie können sie im Storybook sehen (nicht alle Zustände werden erwähnt). Wir werden im letzten Abschnitt dieses Tutorials eine große Anzahl von Geschichten für die Schaltfläche schreiben.

Erkunden Sie verschiedene Abschnitte des Bilderbuchs und machen Sie sich mit den verschiedenen Abschnitten vertraut. Wir werden einige davon im Tutorial behandeln.

Schreiben wir unsere erste Geschichte.

Märchenbuch testen

Wir haben gesehen, wie das Märchenbuch läuft und einige Beispiele darin.

  • Erstellen Sie einen Ordner namens Button im Ordner src.
  • Erstellen Sie Dateien namens Button.jsx, Button.css und constants.js
  • Platzieren Sie den jeweiligen Code aus den folgenden Snippets in den Dateien.

Button.jsx

import React, { Component } from "react";
import PropTypes from "prop-types";

import "./Button.css";

import { buttonTypes, buttonVariants, buttonSizes } from "./constants";

class Button extends Component {
    static defaultProps = {
        isDisabled: false,
        type: "filled",
        variant: "oval",
        size: "medium",
        backgroundColor: "#1ea7fd",
        textColor: "#ffffff",
    };

    static buttonTypes = buttonTypes;
    static buttonVariants = buttonVariants;
    static buttonSizes = buttonSizes;

    renderButton = () => {
        const {
            text,
            isDisabled,
            type,
            variant,
            size,
            backgroundColor,
            textColor,
            onClick,
        } = this.props;
        return (
            <button
                onClick={onClick}
                className={`default ${variant} ${size} ${
                    isDisabled ? "disabled" : ""
                }`}
                style={
                    type === buttonTypes.outline
                        ? {
                              border: `1px solid ${backgroundColor}`,
                              color: "#000000",
                              backgroundColor: "transparent",
                          }
                        : {
                              backgroundColor: `${backgroundColor}`,
                              border: `1px solid ${backgroundColor}`,
                              color: textColor,
                          }
                }
                disabled={isDisabled}
            >
                {text}
            </button>
        );
    };

    render() {
        return this.renderButton();
    }
}

Button.propTypes = {
    text: PropTypes.string,
    isDisabled: PropTypes.bool,
    type: PropTypes.oneOf([buttonTypes.outline, buttonTypes.filled]),
    variant: PropTypes.oneOf([buttonVariants.oval, buttonVariants.rectangular]),
    size: PropTypes.oneOf([
        buttonSizes.small,
        buttonSizes.medium,
        buttonSizes.large,
    ]),
    backgroundColor: PropTypes.string,
    textColor: PropTypes.string,
    onClick: PropTypes.func,
};

export { Button };

Button.css

.default {
    border: none;
    cursor: pointer;
    background-color: transparent;
}

.default:focus {
    outline: none;
}

.disabled {
    opacity: 0.75; 
    cursor: not-allowed;
}
.small {
    font-size: 12px;
    padding: 4px 8px;
}

.medium {
    font-size: 14px;
    padding: 8px 12px;
}

.large {
    font-size: 16px;
    padding: 12px 16px;
}

.oval {
    border-radius: 4px;
}

.rectangular {
    border-radius: 0;
}

konstanten.js

export const buttonTypes = {
    outline: "outline",
    filled: "filled",
};

export const buttonVariants = {
    oval: "oval",
    rectangular: "rectangular",
};

export const buttonSizes = {
    small: "small",
    medium: "medium",
    large: "large",
};

Was ist das für ein Code?

  So verhindern Sie, dass Google Maps Standortdaten von Ihrem Telefon sammelt

Wir haben eine gemeinsame Komponente für Button geschrieben, die auf unterschiedliche Weise verwendet werden kann. Jetzt haben wir eine Komponente, die verschiedene Zustände haben kann.

Lassen Sie uns unsere erste Geschichte schreiben, indem Sie die folgenden Schritte ausführen.

  • Erstellen Sie eine Datei namens Button.stories.jsx
  • Importieren Sie React und unsere Button-Komponente in die Datei.
  • Definieren Sie nun einen Titel oder Pfad für unsere Komponentengeschichten. Wir werden es mit dem folgenden Code definieren.
export default {
   title: ‘common/Button’,
}

Der obige Code platziert alle Storys, die sich in der aktuellen Datei befinden, im Verzeichnis common/Button/.

  • Exportieren Sie eine Schaltfläche mit obligatorischen Requisiten wie folgt.
export const defaultButton = () => (
    <Button text=”Default Button” onClick={() => {}} />
);

Wir haben unsere erste Geschichte abgeschlossen. Führen Sie das Storybook mit dem folgenden Befehl aus und sehen Sie sich die Ausgabe an.

npm run storybook

Wir werden am Ende noch mehr Geschichten schreiben, keine Sorge.

Wie ist es in der Frontend-Entwicklung nützlich?

Was ist der Hauptvorteil der Verwendung eines Bilderbuchs?

Nehmen wir an, wir arbeiten in einem Team von 10 Mitgliedern. Und wir müssen gemeinsame Komponenten überprüfen, die jeder für das aktuelle Arbeitsprojekt geschrieben hat.

Wie können wir das machen?

Wir müssen zu jeder gemeinsamen Komponente gehen, um sie zu überprüfen. Aber es ist zeitaufwändig und für uns kein bevorzugter Weg. Hier kommt unser neues Gästebuch.

Wie können wir es nutzen, um unser Problem zu lösen?

Wir können Geschichten für die gemeinsamen Komponenten (alle UI-Komponenten) mit Storybook schreiben. Und wann immer Ihr Teamkollege die gemeinsamen Komponenten anderer überprüfen möchte, führt er einfach den Storybook-Server aus und sieht dort alle UI-Komponenten, wie wir oben gesehen haben.

Mit den gerenderten Komponenten im Storybook können wir noch viel mehr machen. Storybook hat ein Konzept namens Addons, das unseren Geschichten Superkräfte verleiht.

Angenommen, wir müssen die Reaktionsfähigkeit der UI-Komponenten im Storybook selbst überprüfen, wir können ein Addon namens Viewport im Storybook verwenden. Wir werden in den kommenden Abschnitten mehr über die Addons erfahren.

Arbeiten mit Storybook

In diesem Abschnitt werden wir verschiedene Geschichten schreiben, die verschiedene Zustände unserer gemeinsamen Komponente Button definieren.

Geschichten zu schreiben ist gar nicht so schwer. Eine Story definiert einen Zustand einer Komponente. Wenn Sie die Requisiten einer Komponente sehen, werden Sie leicht verschiedene Anwendungsfälle der Komponente verstehen.

Lassen Sie uns einige Geschichten schreiben, indem wir optionale Requisiten geben.

export const largeButton = () => (
    <Button text="Large Button" onClick={() => {}} size="large" />
);
export const outlineSmallButton = () => (
    <Button
        text="Outline Small Button"
        onClick={() => {}}
        size="small"
        type="outline"
    />
);
export const rectangularLargeButton = () => (
    <Button
        text="Rectangular Large Button"
        onClick={() => {}}
        size="large"
        variant="rectangular"
    />
);


export const disabledButton = () => (
    <Button text="Disabled Button" onClick={() => {}} isDisabled={true} />
);


export const warningButton = () => (
    <Button
        text="Warning Button"
        onClick={() => {}}
        backgroundColor="orange"
    />
);

Die obigen drei Geschichten definieren verschiedene Anwendungsfälle unserer Komponente Button. Jetzt sind Sie an der Reihe, einige andere Fälle von Geschichten für unsere gemeinsame Komponente hinzuzufügen. Versuchen Sie, disabledSamllRectangularButton, DangerButton, SuccessDisabledButton usw. hinzuzufügen.

  So ändern Sie NumPy-Arrays in Python

Ich werde keinen Code für die oben genannten Fälle bereitstellen. Man muss es selbst schreiben, um es zu verstehen. Sie können den vollständigen Geschichtencode sehen, den wir bis jetzt geschrieben haben.

import React from "react";

import { Button } from "./Button";

export default {
    title: "src/common/Button",
};

export const defaultButton = () => (
    <Button text="Default Button" onClick={() => {}} />
);

export const largeButton = () => (
    <Button text="Large Button" onClick={() => {}} size="large" />
);

export const outlineSmallButton = () => (
    <Button
        text="Outline Small Button"
        onClick={() => {}}
        size="small"
        type="outline"
    />
);

export const rectangularLargeButton = () => (
    <Button
        text="Rectangular Large Button"
        onClick={() => {}}
        size="large"
        variant="rectangular"
    />
);

export const disabledButton = () => (
    <Button text="Disabled Button" onClick={() => {}} isDisabled={true} />
);

export const warningButton = () => (
    <Button
        text="Disabled Button"
        onClick={() => {}}
        backgroundColor="orange"
    />
);

Jetzt haben Sie das Schreiben von Geschichten für eine Komponente vollständig im Griff.

Lassen Sie uns in den nächsten Abschnitt springen, in dem wir etwas über Addons erfahren und wie sie unsere Geschichten verbessern.

Märchenbuch-Addons

Wir haben standardmäßig mehrere Addons verfügbar. In diesem Abschnitt werden wir die nützlichsten Addons für unsere Entwicklung untersuchen.

Lassen Sie uns unsere Button-Geschichten verbessern.

Kontrollen

Steuerelemente fügen eine Funktion hinzu, um der Komponente im Storybook selbst benutzerdefinierte Requisiten zu geben. Für unsere Button-Komponente können wir Steuerelemente hinzufügen, um die verschiedenen Requisiten im Storybook zu ändern.

Nehmen wir an, wir müssen die beste Farbe für die Hintergrundfarbe des Buttons herausfinden. Es wird zeitaufwändig sein, wenn wir es testen, um die Hintergrundfarbe zu überprüfen, indem wir der Komponente eine nach der anderen geben. Stattdessen können wir ein Steuerelement hinzufügen, mit dem wir die andere Farbe im Storybook auswählen können. Wir können die Hintergrundfarbe im Bilderbuch selbst testen.

Sehen wir uns an, wie Sie unseren Button-Storys Steuerelemente hinzufügen.

Zuerst müssen wir alle Requisiten unterhalb des Titels wie folgt definieren.

export default {
    title: "src/common/Button",
    argTypes: {
        text: { control: "text" },
        backgroundColor: { control: "color" },
        isDisabled: { control: "boolean" },
        size: {
            control: { type: "select", options: ["small", "medium", "large"] },
        },
        type: {
            control: { type: "select", options: ["filled", "outline"] },
        },
        variant: {
            control: { type: "select", options: ["oval", "rectangular"] },
        },
    },
};

Trennen Sie als Nächstes die Requisiten von der Komponente und geben Sie sie wie folgt als Argumente an.

export const outlineSmallButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
outlineSmallButton.args = {
    text: "Outline Small Button",
    size: "small",
    type: "outline",
};

Sie können die Steuerelemente am unteren Rand des Komponentenvorschaufensters sehen.

Sie können die Registerkarte „Steuerelemente“ unten im Vorschaufenster der Komponente sehen. Spielen Sie darum herum.

Aktualisieren Sie alle Geschichten wie oben. Dies ist alles eher so, als würde man die Syntax der Storybook-Addons kennen. In den argTypes haben wir verschiedene Arten von Steuerelementen verwendet. Sie finden alle Steuerelemente, die im Storybook vorhanden sind hier.

Aktualisierte Schaltflächengeschichten sehen wie folgt aus.

import React from "react";

import { Button } from "./Button";

export default {
    title: "src/common/Button",
    argTypes: {
        text: { control: "text" },
        backgroundColor: { control: "color" },
        isDisabled: { control: "boolean" },
        size: {
            control: { type: "select", options: ["small", "medium", "large"] },
        },
        type: {
            control: { type: "select", options: ["filled", "outline"] },
        },
        variant: {
            control: { type: "select", options: ["oval", "rectangular"] },
        },
    },
};

export const defaultButton = (args) => <Button {...args} onClick={() => {}} />;
defaultButton.args = {
    text: "Default Button",
};

export const largeButton = (args) => (
    <Button {...args} onClick={() => {}} size="large" />
);
largeButton.args = {
    text: "Large Button",
};

export const outlineSmallButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
outlineSmallButton.args = {
    text: "Outline Small Button",
    size: "small",
    type: "outline",
};

export const rectangularLargeButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
rectangularLargeButton.args = {
    text: "Rectangular Large Button",
    size: "large",
    variant: "rectangular",
};

export const disabledButton = (args) => <Button {...args} onClick={() => {}} />;
disabledButton.args = {
    text: "Disabled Button",
    isDisabled: true,
};

export const warningButton = (args) => <Button {...args} onClick={() => {}} />;
warningButton.args = {
    text: "Warning Button",
    backgroundColor: "orange",
};

Aktionen

Aktionen sind Ereignisse in JavaScript. Wir können auf eine Schaltfläche klicken, die ein Ereignis in JavaScript ist. Mit dem Actions-Addon können wir einige Aktionen auf Knopfdruck ausführen.

  Warum eine AMD 5000-CPU Intels CPUs für Spiele schlagen könnte

Mit Aktionen können wir testen, ob die Events richtig funktionieren oder nicht. Deaktivierte Schaltflächen können nicht angeklickt werden und aktivierte Schaltflächen müssen anklickbar sein. Wir können es mit den Aktionen sicherstellen.

Sehen wir uns an, wie Sie dem Schaltflächenklick eine Aktion hinzufügen.

Wir haben den onClick-Requisiten zuvor eine anonyme Funktion gegeben. Jetzt müssen wir es aktualisieren.

  • Importieren Sie die Aktion aus dem Storybook-Addon mit der folgenden Anweisung.
import { action } from "@storybook/addon-actions";
  • Ersetzen Sie alle () => {} durch die folgende Anweisung.
action("Button is clicked!")

Gehen Sie jetzt zum Storybook und klicken Sie auf eine Schaltfläche. Die Meldung wird unter der Registerkarte „Aktionen“ gedruckt, die sich neben der Registerkarte „Steuerelemente“ befindet. Die Nachricht wird nicht gedruckt, wenn Sie auf die deaktivierte Schaltfläche klicken, da sie deaktiviert ist.

Wir können die Aktion für verschiedene Ereignisse wie onChange, onMouseOver, onMouseOut usw. verwenden, um sicherzustellen, dass sie ordnungsgemäß funktionieren. Versuchen Sie, dasselbe für onChange für ein Eingabeelement zu implementieren.

Siehe die Dokumentation für Aktionen hier.

Hintergrund

Wir können den Hintergrund des Vorschaufensters mit dem Hintergrund-Addon ändern. Wir müssen keinen Code schreiben. Ändern Sie es einfach im Storybook. Sie können das gif unten sehen.

Ansichtsfenster

Auch das Ansprechverhalten unserer Komponenten können wir im Storybook testen. Sehen Sie sich das GIF unten an, um mehr über die Ansichtsfensteroptionen zu erfahren.

Dokumente

Wir können unsere Komponenten im Storybook mit dem Docs-Addon dokumentieren. Es ist nützlicher, wenn wir im Team arbeiten. Sie werden die Komponente lesen und direkt verstehen. Das spart den Entwicklern viel Zeit.

Im Vorschaufenster der Komponenten von Storybooks können Sie oben rechts auf der Registerkarte Canvas Docs sehen. Es enthält alle Dokumente aller Geschichten einer Komponente. Wir müssen Button.stories.mdx verwenden, wenn wir für die Komponente dokumentieren möchten, die sowohl Markdown als auch Komponentenrendering enthält. Wir schreiben einfach zusätzlichen Markdown-Code zusammen mit den Komponenten-Storys hinein.

Wir schreiben ein Dokument für unsere Geschichten. Der Code umfasst Markdown und Komponentenrendering. Es ist alles nur das Erlernen der Syntax. Sie werden es auf den ersten Blick sehen.

Sehen wir uns den Button.stories.mdx-Dokumentcode an.

<!--- Button.stories.mdx -->

import {
    Meta,
    Story,
    Preview,
    ArgsTable
} from '@storybook/addon-docs/blocks';

import { Button } from './Button';

<Meta title="MDX/Button" component={Button} />

# Button Documentation

With `MDX` we can define a story for `Button` right in the middle of our
Markdown documentation.

<ArgsTable of={Button} />

export const Template = (args) => <Button {...args} />

## Default Button
We can write the documentation related to the Default Button
<Preview>
    <Story name="Default Button" args={{
        text: 'Default Button'
    }}>
    {Template.bind({})}
   </Story>
</Preview>

## Large Button
We are writing sample docs for two stories, you can write rest of them
<Preview>
    <Story name="Large Button" args={{
        text: "Large Button",
        }}>
        {Template.bind({})}
    </Story>
</Preview>

Erfahren Sie mehr über die dokumentierenden Komponenten hier.

Sie können mehr über Add-Ons erfahren hier.

Fazit

Ich hoffe, Ihnen hat das Tutorial gefallen und Sie haben etwas über das Märchenbuch gelernt. Und nutzen Sie es effektiv in Ihrem Team, um Ihre Arbeit produktiv zu gestalten.

Neu bei React? Sehen Sie sich diese Lernressourcen an.

Viel Spaß beim Programmieren 🙂