Skip to main content

Die Kunst des bedingten Renderings: Tipps und Tricks für React- und Next.js-Entwickler

Artikel von

Kumar Harsh

blog feature open source security

30. Oktober 2023

0 Min. Lesezeit

Bedingtes Rendering ist eine Technik, mit der in Webanwendungen abhängig von einer Bedingung – etwa dem Authentifizierungsstatus, den Berechtigungen eines Nutzers oder dem Anwendungsstatus – gezielt eine Komponente aus mehreren möglichen Komponenten gerendert wird. Damit lassen sich auch zahlreiche zentrale React-UI-Konzepte umsetzen, etwa clientseitiges Routing und Lazy Loading.

In diesem Artikel erfahren Sie mehr über die Vorteile des bedingten Renderings, seine Unterschiede zum bedingten Routing und wie Sie beides in React, Next.js und Remix umsetzen.

Vorteile des bedingten Renderings in React

In Apps, die mit React oder ähnlichen Frameworks entwickelt wurden, bietet bedingtes Rendering zahlreiche Vorteile, darunter kürzere Ladezeiten.

Die Ladezeit einer Webanwendung wird von der Größe des Document Object Model (DOM) der geladenen Seite beeinflusst. Zu viele Elemente – insbesondere solche, die erst angezeigt werden, wenn Nutzer nach unten scrollen – können zu einer unnötig großen DOM-Größe führen und die Performance Ihrer Anwendung beeinträchtigen.

In diesem Fall lässt sich Lazy Loading einsetzen, eine beliebte Technik, bei der Ressourcen erst bei Bedarf geladen werden. Damit kann das Rendering einer Komponente so lange aufgeschoben werden, bis Nutzer nach unten scrollen und sie in den Viewport gelangt. Eine der beliebtesten Lazy-Loading-Bibliotheken für React, react-lazyload, nutzt bedingtes Rendering, um Komponenten erst dann zu rendern, wenn sie in den Viewport des Browsers gelangen – also für Nutzer sichtbar werden.

Neben der Performance kann bedingtes Rendering auch die User Experience verbessern. Damit können Sie Ihre UI anhand von Nutzereigenschaften anpassen, etwa anhand des Authentifizierungsstatus (d. h. an derselben Stelle auf dem Bildschirm eine Anmeldeschaltfläche für nicht authentifizierte und eine Abmeldeschaltfläche für authentifizierte Nutzer anzeigen) oder der Zugriffsberechtigungen (d. h. Eigentümern von Inhalten wie Tweets Bearbeitungsoptionen und detaillierte Analysen anzeigen, während andere Nutzer nur eingeschränkte Informationen sehen).

Außerdem hilft bedingtes Rendering dabei, clientseitige Vorgänge wie das Abrufen von Daten und die Kommunikation mit dem Backend elegant zu handhaben. Während ein Vorgang ausgeführt wird, können Sie beispielsweise bedingt eine Ladeanzeige einblenden oder eine leere Liste ausblenden, während Daten aus einer Remote-Quelle geladen werden.

Bedingtes Rendering ermöglicht auch clientseitiges Routing in Single-Page-React-Apps, etwa mit dem Paket react-router.

Zusammenfassend lässt sich sagen: Bedingtes Rendering ist eine der wichtigsten Techniken in React.

Bedingtes Rendering vs. bedingtes Routing

Wenn es um bedingtes Rendering geht, kommt oft auch bedingtes Routing zur Sprache. Ähnlich wie bedingtes Rendering steuert bedingtes Routing anhand von Bedingungen wie dem Nutzer- oder Anwendungsstatus, was Nutzer zu sehen bekommen. Statt Komponenten zu rendern oder zu entfernen, leitet es Nutzer jedoch von einer Route (oder Seite) zu einer anderen weiter. Das ist hilfreich, wenn es um Zugriffskontrollen geht.

Auf Web-Apps kann direkt über URLs zugegriffen werden. Das bedeutet, dass Nutzer die URL einer Seite in Ihrer App speichern und weitergeben können – unabhängig davon, ob die Seite öffentlich zugänglich ist. Bei privilegierten Seiten (nicht öffentlichen Seiten, auf die nur Nutzer mit bestimmten Rollen zugreifen können, etwa Seiten für persönliche Profile und Einstellungen) können die URLs missbraucht werden, um Zugriff auf geschützte Inhalte zu erlangen.

Mit bedingtem Routing kann eine React-App prüfen, ob eine eingehende Anfrage zum Rendern einer Seite über die nötigen Berechtigungen für den Zugriff auf die Route verfügt. Fehlen diese Berechtigungen, wird das Rendering verweigert und die Anfrage zu einer anderen Seite umgeleitet. Auf der Zielseite werden Nutzer häufig aufgefordert, sich zu authentifizieren, oder darüber informiert, dass der Zugriff verweigert wurde.

Um bedingtes Routing in Aktion zu erleben, öffnen Sie in einem neuen Inkognito-Fenster https://mail.google.com/mail. Sie werden zur Google-Anmeldeseite weitergeleitet. So funktioniert bedingtes Routing im Hintergrund.

Bedingtes Routing in einer SPA bietet jedoch keine Sicherheitsgarantie. Noch bevor Ihre React-App (als Single-Page-App) nicht authentifizierte Nutzer weiterleitet, enthält ihr JavaScript-Quellcode weiterhin die Inhalte der privilegierten Seite. Das kann zu unbefugtem Zugriff auf geschützte Daten führen. Richten Sie die authentifizierungsbezogene bedingte Weiterleitung deshalb am besten serverseitig ein, beispielsweise mit Frameworks wie Next.js und Remix.

Bedingtes Rendering in React umsetzen

Nachdem Sie nun mehr über bedingtes Rendering erfahren haben, lernen Sie im folgenden Abschnitt, wie Sie es in einer React-App mit einem der grundlegenden Programmierkonzepte umsetzen: der if…else-Anweisung.

Erstellen Sie zunächst mit den folgenden Befehlen eine neue React-App:

npx create-react-app conditional-rendering-react
cd conditional-rendering-react
npm install

Sobald die App bereit ist, fügen Sie den folgenden Code in die Datei src/App.js ein:

import { useState } from "react"

// Define two components
const LoginButton = (props) => {
  return <>
  <div>You are logged out</div>
  <div><button onClick={props.toggleLoggedIn}>Log In</button></div>
  </>
}

const LogoutButton = (props) => {
  return <>
  <div>You are now logged in</div>
  <div><button onClick={props.toggleLoggedIn}>Log Out</button></div>
  </>
}

function App() {
  // Define a state that the condition will be based upon
  const [loggedIn, setLoggedIn] = useState(false);

  // Define a function that can change the condition value
  const toggleLoggedIn = () => {
    setLoggedIn((currState) => {
        return !currState;
    })
  }

  // Use an if...else statement to render one out of two components based on the login state
  if (loggedIn)
    return <LogoutButton toggleLoggedIn={toggleLoggedIn} />
  else
    return <LoginButton toggleLoggedIn={toggleLoggedIn} />
}

export default App;

Inline-Kommentare im Code erläutern die einzelnen Schritte.

Starten Sie die App anschließend mit diesem Befehl:

npm start

Wenn Sie die App-URL aufrufen (d. h. http://localhost:3000), sehen Sie auf dem Bildschirm einen Text und eine Schaltfläche:

Browserseite mit der Meldung „Sie sind abgemeldet“ und einer Schaltfläche „Anmelden“.

Klicken Sie auf die Schaltfläche Log In, um den Status zu ändern und ein erneutes Rendering auszulösen. Sie werden feststellen, dass sich sowohl der Text als auch die Schaltfläche ändern und nun die Elemente für einen angemeldeten Nutzer angezeigt werden:

Browserseite unter localhost:3000 mit der Meldung „Sie sind jetzt angemeldet“ und einer Schaltfläche „Abmelden“

Das war's schon! So einfach lässt sich bedingtes Rendering in React umsetzen. Als Nächstes erfahren Sie, wie das in einer Next.js-App funktioniert.

Bedingtes Rendering und bedingtes Routing in Next.js umsetzen

Next.js ist ein meinungsstarkes, produktionsorientiertes Open-Source-Framework auf React-Basis, mit dem Sie hochperformante Web-Apps entwickeln können. Es wurde 2016 von Vercel veröffentlicht und hat sich seitdem zu einem der führenden React-basierten Frameworks in der Webentwicklung entwickelt.

Next.js unterstützt standardmäßig serverseitiges und statisches Rendering und bietet benutzerfreundliche Lösungen für typische Entwicklungsaufgaben wie das Abrufen von Daten, Routing und Server-Runtimes.

Bedingtes Rendering in Next.js umsetzen

Da die JSX-Syntax in Next.js und React einheitlich ist, können Sie bedingtes Rendering in Next.js genauso einsetzen wie in React.

Erstellen Sie zunächst mit dem folgenden Befehl eine neue Next.js-App:

npx create-next-app conditionals-next

Folgen Sie den Anweisungen auf dem Bildschirm, um Ihre App zu erstellen. Sie können die Standardoptionen wählen (außer bei TypeScript, wo Sie No auswählen müssen). Sobald das Projekt erstellt ist, fügen Sie den folgenden Code in die Datei pages/index.js ein:

import { useState } from "react";

// Define two components
const LoginButton = (props) => {
  return <>
    <div>You are logged out</div>
    <div><button onClick={props.toggleLoggedIn}>Log In</button></div>
  </>
}

const LogoutButton = (props) => {
  return <>
    <div>You are now logged in</div>
    <div><button onClick={props.toggleLoggedIn}>Log Out</button></div>
  </>
}

export default function Home() {
  // Define a state that the condition will be based upon
  const [loggedIn, setLoggedIn] = useState(false);

  // Define a function that can change the condition value
  const toggleLoggedIn = () => {
    setLoggedIn((currState) => {
        return !currState;
    })
  }

  // Use the ternary conditional operator to render one out of two components based on login state
  return loggedIn 
  ? <LogoutButton toggleLoggedIn={toggleLoggedIn} /> 
  : <LoginButton toggleLoggedIn={toggleLoggedIn} />
}

Inline-Kommentare im Code erläutern die einzelnen Schritte. Ein wesentlicher Unterschied zum React-Beispiel: Hier wird der ternäre Bedingungsoperator in JavaScript verwendet, um beim Rendering eine von zwei Komponenten auszuwählen. Mit dem folgenden Befehl können Sie die App starten:

npm run dev

Sobald die App gestartet ist, sehen Sie unter http://localhost:3000 etwa Folgendes:

Browserseite unter localhost:3000 mit der Meldung „Sie sind abgemeldet“ und einer Schaltfläche „Anmelden“

Auch hier können Sie auf die Schaltfläche Log In klicken, um den Status zu ändern:

Browserseite mit der Anzeige „Sie sind jetzt angemeldet“ und einer Schaltfläche „Abmelden“

Bedingtes Routing in Next.js umsetzen

Auch bedingtes Routing lässt sich in Next.js 10 und höher einfach umsetzen. Erstellen Sie zunächst im Verzeichnis conditionals-next/pages eine neue Datei namens profile.js und fügen Sie den folgenden Codeausschnitt ein:

// This is the profile page
const Profile = () => {
  return <div>This is your profile</div>
}

// This function is called on the server side before the page is rendered
// Redirecting from this method means that the user will not see the page even for a flash of a second (which often happens in client-side redirection)
export async function getServerSideProps(context) {
    const allowAccess = false; // This is usually deduced from the authentication state of the user

    if (!allowAccess) {

        console.log("Redirecting to home...")

        return {
            redirect: {
                permanent: false,
                destination: "/"
            }
        }
    } else
        return { props: {} }
}

export default Profile

Starten Sie die App erneut und rufen Sie http://localhost:3000/profile auf. Sie werden sofort zur Startseite weitergeleitet (d. h. zur Route /). Im Terminal finden Sie den Weiterleitungs-Log:

# ... other output here
wait  - compiling...
event - compiled client and server successfully in 109 ms (199 modules)
wait  - compiling /profile (client and server)...
event - compiled client and server successfully in 114 ms (202 modules)
Redirecting to home...

Wenn Sie den Wert von allowAccess auf true setzen, können Sie die Profilseite aufrufen:

Browserfenster unter localhost:3000/profile mit der Überschrift „Das ist Ihr Profil“ auf einer schwarzen Seite

Bedingtes Rendering und bedingtes Routing in Remix umsetzen

Remix ist ein weiteres aufstrebendes React-basiertes Framework für Web-Apps. Es orientiert sich an Webstandards und unterstützt Sie dabei, bessere User Experiences zu schaffen. Remix wurde 2021 als Open Source veröffentlicht und hat sich zu einem starken Konkurrenten von Next.js entwickelt.

Remix ist ein Framework mit vollständig serverseitigem Rendering und bietet Funktionen wie integrierte Error Boundaries und die Verarbeitung von Übergängen.

Bedingtes Rendering in Remix umsetzen

Da Remix auf React basiert, können Sie bedingtes Rendering ähnlich wie in React und Next.js umsetzen.

Erstellen Sie zunächst mit dem folgenden Befehl ein neues Remix-Projekt:

npx create-remix@latest

Folgen Sie den Anweisungen, um Ihr Projekt zu erstellen. Wählen Sie unbedingt JavaScript statt TypeScript. Sobald das Projekt erstellt ist, fügen Sie den folgenden Codeausschnitt in app/routes/index.jsx ein:

import { useState } from "react";

// Define two components
const LoginButton = (props) => {
  return <>
    <div>You are logged out</div>
    <div><button onClick={props.toggleLoggedIn}>Log In</button></div>
  </>
}

const LogoutButton = (props) => {
  return <>
    <div>You are now logged in</div>
    <div><button onClick={props.toggleLoggedIn}>Log Out</button></div>
  </>
}

export default function Index() {
  // Define a state that the condition will be based upon
  const [loggedIn, setLoggedIn] = useState(false);

  // Define a function that can change the condition value
  const toggleLoggedIn = () => {
    setLoggedIn((currState) => {
        return !currState;
    })
  }

  // Use a switch statement to render one of two components based on login state
  switch(loggedIn) {
    case true: return <LogoutButton toggleLoggedIn={toggleLoggedIn} />
    case false: return <LoginButton toggleLoggedIn={toggleLoggedIn} />
    default: return null
  }
}

Inline-Kommentare im Code erläutern die einzelnen Schritte. Statt einer if...else-Anweisung oder eines ternären Bedingungsoperators wird in diesem Beispiel mit einer switch-Anweisung entschieden, welche Komponente gerendert werden soll.

Wie in den vorherigen Beispielen sieht die Startseite unter http://localhost:3000 folgendermaßen aus:

Browserseite unter localhost:3000 mit der Anzeige „Sie sind abgemeldet“ und einer Schaltfläche „Anmelden“

Wie zuvor können Sie auf die Schaltfläche Log In klicken, um den Status zu ändern:

Browserseite mit der Meldung „Sie sind jetzt angemeldet“ und einer Schaltfläche „Abmelden“

Bedingtes Routing in Remix umsetzen

Wie beim serverseitigen bedingten Routing in Next.js können Sie es auch in Remix umsetzen. Erstellen Sie im Verzeichnis conditionals-remix/app/routes eine neue Datei namens profile.jsx und fügen Sie den folgenden Code ein:

import { redirect } from '@remix-run/node'

const Profile = () => {
    return <div>This is your profile</div>
}

export const loader = () => {
    const allowAccess = false; // This is usually deduced from authentication state of the user

    if (!allowAccess) {
        console.log("Redirecting to home...")

        return redirect('/')
    }

    return null
}

export default Profile

Hier wird eine Loader-Funktion statt der Funktion getServerSideProps verwendet, da Remix Loader zum Laden von Daten in Komponenten unterstützt, während diese auf dem Server gerendert werden (ähnlich wie getServerSideProps in Next.js). Außerdem wird eine Hilfsfunktion redirect zurückgegeben (ähnlich der Next.js-Funktion redirect), um eine Weiterleitung auszulösen, wenn allowAccess auf false gesetzt ist.

Rufen Sie http://localhost:3000/profile auf. Sie werden erneut sofort zur Startseite weitergeleitet (d. h. zur Route /). Im Terminal finden Sie den Weiterleitungs-Log:

# ... other output here
💿 Rebuilding...
💿 Rebuilt in 100ms
GET / 200 - - 17.179 ms
Redirecting to home...        #=== here it is
GET /profile 302 - - 7.107 ms
GET / 200 - - 6.564 ms

Wenn Sie den Wert von allowAccess auf true setzen, können Sie die Profilseite aufrufen:

Browserfenster mit einer Profilseite und der Überschrift „Das ist Ihr Profil“ unter localhost:3000/profile.

Weitere Überlegungen zum bedingten Rendering

Beim Einsatz von bedingtem Rendering fragen Sie sich vielleicht, wie es sich auf das virtuelle DOM auswirkt. Sind die verschiedenen Methoden des bedingten Renderings gleich effizient? Beeinträchtigt eine neue Komponente oder Higher-Order-Komponente (HOC), die die Details des bedingten Renderings abstrahiert, das DOM (und die Performance) Ihrer App? In diesem Abschnitt finden Sie die Antworten.

Bedingtes Rendering und JSX

Wie Sie bedingtes Rendering umsetzen, wirkt sich nicht auf das DOM und die Performance Ihrer App aus. Sehen Sie sich das folgende Beispiel an:

if (loggedIn)
  return <button>Log Out</button>
else
  return <button>Log In</button>

Sie können es mit dem ternären Bedingungsoperator auch so schreiben:

return <button>{loggedIn ? "Log Out" : "Log In"}</button>

In beiden Fällen gibt die übergeordnete Komponente eine der beiden Komponenten zurück (d. h. LoginButton oder LogoutButton), und das DOM wird exakt gleich verändert. Vielleicht wenden Sie ein, dass dadurch unterschiedliche Instanzen des Button-Tags zurückgegeben werden könnten. Das stimmt jedoch nicht. JSX-Elemente wie Schaltflächen und andere Tags sind keine Instanzen. Sie beschreiben lediglich die endgültige HTML-Struktur oder skizzieren deren Grundgerüst.

Solange Sie dieselben Elemente in derselben Struktur zurückgeben, wirkt sich das gleich auf das DOM aus. Sie können das Rendering also problemlos hinter Komponenten abstrahieren, solange die JSX-Struktur gleich bleibt.

Das ermöglicht auch interessante Szenarien: Ein Status kann von zwei strukturell identischen Komponenten gemeinsam genutzt werden, von denen jeweils nur eine bedingt an derselben Stelle im DOM gerendert wird. Auf der React-Website erfahren Sie mehr darüber. Dort wird veranschaulicht, wie stark sich ein einfacher ternärer Operator in JSX auf das Verhalten Ihrer App auswirken kann.

Verschachtelte Komponenten und bedingtes Rendering

Die Definition von Komponenten innerhalb anderer Komponenten zu verschachteln, gilt als Anti-Pattern. Einer der Hauptgründe dafür ist, dass eine verschachtelte Komponente immer neu erstellt wird, wenn ihre übergeordnete Komponente erneut gerendert wird – unabhängig von ihrer Position im DOM-Baum. Dieses Verhalten unterscheidet sich von dem, was Sie zuvor gesehen haben, denn die Definition der verschachtelten Komponente wird zur Laufzeit beim erneuten Rendern der übergeordneten Komponente neu erstellt. Das ähnelt der Erstellung einer neuen Instanz der Definition der verschachtelten Komponente und verursacht daher dieses Problem.

Fazit und weitere Ressourcen

Bedingtes Rendering wirkt auf den ersten Blick recht einfach – und ist es auch –, ist aber eine sehr leistungsstarke Methode, um die Performance und Benutzerfreundlichkeit von React-Apps zu verbessern. In diesem Artikel haben Sie die Vorteile kennengelernt und erfahren, wie sich bedingtes Rendering vom bedingten Routing unterscheidet und wie Sie es in React, Next.js und Remix implementieren.

Weitere Informationen zu bedingtem Rendering und dazu, wie React den Status bei erneuten Renderings verwaltet, finden Sie in der neuen React-Dokumentation.

Bei der Arbeit an React-Apps müssen Sie häufig npm-Pakete auswählen und installieren, um zusätzliche Funktionen hinzuzufügen, etwa für Routing und Statusverwaltung. Snyk Advisor hilft Ihnen dabei, das richtige npm-Paket für Ihr Projekt zu finden und gleichzeitig hohe Sicherheitsstandards für Ihre App einzuhalten. Sehen Sie sich auch unsere Liste mit 10 Best Practices für Sicherheit an, die Sie bei der Arbeit mit React befolgen sollten.

Snyk lässt sich auch als IDE-Erweiterung verwenden, um unsicheren Code in React-Codebasen zu finden und Sie dabei zu unterstützen, Sicherheitslücken in Open-Source-Abhängigkeiten zu beheben.

Starten Sie mit Capture-the-Flag

Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Challenges lösen.

Weiterlesen

feature insights context
Blog

Autonome Angriffe sind bereits Realität. Die Verteidigung muss Schritt halten.

Autonome Angreifer verkürzen das Zeitfenster für die Verteidigung. Erfahren Sie, wie kontinuierliches Erkennen, Beheben, Validieren und Verhindern Sicherheitsteams helfen kann, Schritt zu halten.

Blog

Warum KI-Coding-Agenten immer wieder fehlerhafte Zugriffskontrollen schreiben

KI-Coding-Agenten können Autorisierungslogik erzeugen, die kompiliert und die Prüfung besteht, dabei aber die Daten eines Mandanten für einen anderen offenlegt. Erfahren Sie, warum fehlerhafte Zugriffskontrollen schwer zu erkennen sind und wie Sie sie verhindern.

Blog

Evo ADS Govern Agent Behavior ist allgemein verfügbar: MCP-Nutzung unter Kontrolle bringen

Evo ADS Govern Agent Behavior ist jetzt allgemein verfügbar und startet mit MCP Governance. Entdecken, genehmigen, überwachen, protokollieren und blockieren Sie die MCP-Server-Nutzung in führenden KI-Coding-Agenten.