HOWTO · React
Schrittweise Implementierung der Expand/Collapse-Funktion in React
Lesen Sie diese Anleitung, um zu erfahren, wie Sie Benutzern das Erweitern/Reduzieren von Inhalten durch Klicken auf eine Schaltfläche ermöglichen. Es ist eine Schritt-für-Schritt-Aufschlüsselung eines praktischen Beispiels.
Auf dieser Seite
Enthält eine Seite lange Abschnitte oder eine Liste von Beiträgen, sollten Leser selbst auswählen können, was sie sehen möchten. In React kann eine Schaltfläche den Zustand aktualisieren. Beim bedingten Rendern lässt sich dieser Zustand nutzen, um einen Container oder ein einzelnes Element ein- oder auszublenden. Entscheidend ist, jede unabhängige Sichtbarkeitsentscheidung separat abzubilden.
Eine Erweitern-/Reduzieren-Funktion in React implementieren
Verwenden Sie für einen einzelnen Abschnitt einen booleschen Zustandswert oder, wenn Elemente unabhängig voneinander gesteuert werden sollen, ein Objekt mit Elementkennungen als Schlüsseln. Nach einer Zustandsänderung rendert React die passende JSX erneut. Für einen einzelnen Abschnitt besteht das Grundmuster aus const [isOpen, setIsOpen] = useState(true), einer Schaltfläche mit onClick={() => setIsOpen(open => !open)} und bedingt gerendertem Inhalt wie {isOpen && <section>...</section>}. Der funktionale Updater liest den aktuellen Wert; der &&-Ausdruck rendert nichts, wenn der Wert false ist.
Das folgende einfache JavaScript-Modell zeigt, wie Kennungen unabhängigen Sichtbarkeitswerten zugeordnet werden. Es ist eigenständig und rendert keine React-Oberfläche:
Führen Sie dieses JavaScript-Modell aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
const postIds = ["post1", "post2", "post3"];
const visible = Object.fromEntries(postIds.map((id) => [id, true]));
visible.post2 = !visible.post2;
console.log(postIds.map((id) => `${id}: ${visible[id]}`).join(", "));
post1: true, post2: false, post3: true
Hier ist eine zusammenhängende React-Komponente, die diese Steuerelemente kombiniert. Importieren Sie in einem Anwendungsmodul * as React sowie useState aus react. Durch die Verwendung von createElement ist die Komponente gültiger JavaScript-Quelltext und zugleich React-Code. Die bereitgestellten Ausführungsnachweise beziehen sich auf das einfache JavaScript-Modell, nicht auf das Rendern durch React. Diese Komponente dient daher zur Veranschaulichung; das ausführbare JavaScript-Modell oben ist davon getrennt.
function PostList({ posts }) {
const postIds = posts.map((post) => post.id);
const [sectionOpen, setSectionOpen] = useState(true);
const [visible, setVisible] = useState(() =>
Object.fromEntries(postIds.map((id) => [id, true]))
);
function togglePost(id) {
setVisible((current) => ({ ...current, [id]: !current[id] }));
}
function setAllVisible(value) {
setVisible(Object.fromEntries(postIds.map((id) => [id, value])));
}
return React.createElement(
"section",
null,
React.createElement(
"button",
{ onClick: () => setSectionOpen((open) => !open) },
sectionOpen ? "Hide posts" : "Show posts"
),
React.createElement(
"button",
{ onClick: () => setAllVisible(true) },
"Show All"
),
React.createElement(
"button",
{ onClick: () => setAllVisible(false) },
"Hide All"
),
sectionOpen &&
React.createElement(
"div",
null,
posts.map((post) =>
React.createElement(
"article",
{ key: post.id },
React.createElement(
"button",
{ onClick: () => togglePost(post.id) },
visible[post.id] ? "Collapse" : "Expand"
),
visible[post.id] &&
React.createElement("p", null, post.text)
)
)
)
);
}
Das Objekt visible ordnet jeder Beitragskennung einen eigenen booleschen Wert zu. Ein Klick auf die Schaltfläche eines Beitrags ändert nur diesen Eintrag; durch die Übernahme von current bleiben die Werte aller anderen Beiträge erhalten. sectionOpen steuert die übergeordnete Liste unabhängig davon. Beim Schließen werden alle gerenderten Kindelemente ausgeblendet, ohne ihre Werte zurückzusetzen. Beim erneuten Öffnen erscheinen daher wieder die zuvor sichtbaren Beiträge. Die Schaltflächen für die Gesamtsteuerung setzen den Wert jedes Elements auf denselben booleschen Wert. Ist der übergeordnete Bereich geschlossen, aktualisiert „Alle anzeigen“ diese Werte trotzdem; die Beitragsinhalte bleiben jedoch verborgen, bis der Bereich wieder geöffnet wird.
Den gesamten Container in React erweitern oder reduzieren
Ein übergeordneter Abschnitt hat einen eigenen Sichtbarkeitszustand. Ändern Sie diesen Wert mit einer Schaltfläche und rendern Sie die gesamte darin enthaltene Liste bedingt, zum Beispiel mit {sectionOpen && <div>{/* list */}</div>}. Ist der übergeordnete Bereich verborgen, wird keines seiner Kindelemente gerendert, selbst wenn die im übergeordneten Zustand gespeicherten Sichtbarkeitswerte weiterhin true sind. Wird der übergeordnete Bereich wieder angezeigt, erscheinen die Elemente, deren Werte nach wie vor auf sichtbar stehen.
Dabei kommt es darauf an, wo der Zustand gespeichert ist: Beim Ausblenden bleiben die Sichtbarkeitswerte der einzelnen Elemente erhalten, wenn sie im übergeordneten Zustand liegen. Bedingtes Rendern hängt jedoch Kindkomponenten aus; ein nur innerhalb dieser Komponenten gespeicherter Zustand geht dabei verloren. Im obigen Beispiel liegen die Sichtbarkeitswerte in PostList, sodass beim erneuten Öffnen dieselben Elemente erscheinen. Wenn beim Schließen des übergeordneten Bereichs alle Elemente zurückgesetzt werden sollen, aktualisieren Sie ihre Sichtbarkeitswerte im selben Ereignishandler. Andernfalls können die Steuerelemente für den übergeordneten Bereich und die einzelnen Elemente unabhängig bleiben. Das CodeSandbox-Beispiel ist die interaktive Demonstration des Ausgangsartikels.
Bestimmte Beiträge in React erweitern oder reduzieren
Verwenden Sie für jedes Element dessen Kennung, um nur den zugehörigen Sichtbarkeitswert abzurufen und zu aktualisieren. Bei einer Zustandsänderung sollte ein neues Objekt erstellt werden, statt das vorhandene zu verändern. Ein funktionaler Updater eignet sich, wenn der nächste Wert vom vorherigen Zustand abhängt: setVisible(current => ({ ...current, [id]: !current[id] })). Die berechnete Eigenschaft [id] wählt den Eintrag des Elements aus, dessen Schaltfläche angeklickt wurde; die Übernahme der übrigen Eigenschaften lässt alle anderen Einträge unverändert.
Innerhalb der Liste kann eine Schaltfläche setVisible für das jeweilige Element aufrufen. Eine Bedingung wie {visible[id] && <Post post={post} />} steuert dann den Inhalt dieses Elements. Wenn sich die Liste ändern kann, leiten Sie das anfängliche Sichtbarkeitsobjekt aus den aktuellen Kennungen ab und berücksichtigen Sie neue oder entfernte Kennungen, sobald sich die Daten ändern. Ein festes Objekt mit manuell eingetragenen Schlüsseln deckt nur die darin aufgeführten Elemente ab.
Alle Beiträge in React erweitern oder reduzieren
Steuerelemente für die Gesamtanzeige setzen den Wert jedes Elements auf denselben booleschen Wert. Leiten Sie das Objekt aus den Kennungen ab, damit Liste und Sichtbarkeitszustand übereinstimmen:
const setAllVisible = (value) => setVisible(Object.fromEntries(postIds.map(id => [id, value])))
Verwenden Sie für „Alle ausblenden“ onClick={() => setAllVisible(false)} und für „Alle anzeigen“ onClick={() => setAllVisible(true)}. Diese Steuerelemente aktualisieren die Werte der einzelnen Elemente. Ist der übergeordnete Container ausgeblendet, ändert „Alle anzeigen“ zwar den Zustand der Kindelemente, deren Inhalt bleibt aber unsichtbar, bis der übergeordnete Bereich wieder angezeigt wird.
Fazit
Verwenden Sie für einen einzelnen Abschnitt einen booleschen Wert und für unabhängig steuerbare Elemente eine Zuordnung von Kennungen zu booleschen Werten. Halten Sie die Sichtbarkeit des übergeordneten Bereichs, die Sichtbarkeit einzelner Elemente und die Aktionen für alle Elemente im Zustand klar getrennt, damit jede Schaltfläche den vorgesehenen Teil der Oberfläche ändert. Das Styling kann das Aussehen der Schaltflächen verändern; der Zustand und das bedingte Rendern bestimmen, was Leser sehen können.