Startseite / Artikel

Erstellung eines konfigurierbaren Auswahlkomponenten für React Native Paper

Ein Leitfaden zur Erstellung und Offenlegung von react-native-paper-select als Open-Source-Projekt, der Suchfunktionen, mehrfache Auswahlmöglichkeiten, gegliederte Listen sowie Leistungsabwägungen behandelt.

Verlag: REACTAPP.TOP12 Min. Lesezeit2663 Wörter

Quellen: I Built a React Native Select Component — and Turned It Into an Open-Source Package: `react-native-paper-select`

Die Erstellung eines echten Dropdown-Menüs in React Native ist fast nie so einfach, wie es klingt

Falls Sie bereits Zeit damit verbracht haben, ein ordentliches Dropdown-Menü in React Native umzusetzen, wissen Sie bereits, dass „nur ein Dropdown“ schnell zu einer weitaus größeren Aufgabe wird.

Man muss schließlich den Auswahlzustand verwalten, Suchfunktionen einbinden, mehrfache Auswahlen unterstützen, lange Listen handhaben, die Benutzeroberfläche so darstellen, dass sie auf Mobilgeräten nativ wirkt, Validierungen hinzufügen und sicherstellen, dass das Ganze visuell in den Rest Ihrer App passt.

Falls Ihr Projekt bereits auf React Native Paper basiert, erscheint es überflüssig, eine separate UI-Bibliothek zu verwenden, nur um ein funktionierendes Auswahlfeld zu erhalten.

Genau dieses Problem soll mit diesem Komponenten gelöst werden.

Ziel war ein wiederverwendbarer Auswahl-Component, der sich perfekt in React Native Paper einfügte, sowohl für die Einzel- als auch für die Mehrfachauswahl geeignet war und jedes Projekt davor bewahrte, immer wieder dasselbe Interaktionsmuster neu zu entwickeln.

Deshalb wurde er von Grund auf erstellt.

Was ursprünglich als recht spezifischer UI-Component begann, entwickelte sich schließlich zu react-native-paper-select – einem Open-Source-Paket für React Native, das heute Suchfunktionen, Mehrfachauswahl, an Chips basierende Anzeige, gegliederte Listen, Auswahl per Radio-Buttons, Bottom Sheets, Menüs sowie eine leistungsorientierte Listendarstellung beinhaltet.

Dieser Artikel behandelt die Motivation hinter seiner Entwicklung, wie sich der Component im Laufe der Zeit verändert hat, die technischen Entscheidungen, die ihn geprägt haben, sowie die Erkenntnisse, die beim Umwandeln eines ursprünglich für eine einzige App entwickelten Tools in eine allgemein einsetzbare Open-Source-Bibliothek gewonnen wurden.

Das Problem

Auf den ersten Blick scheinen Dropdowns unkompliziert zu sein.

Sobald man jedoch tatsächlich mit der Implementierung beginnt, taucht eine lange Liste an Designfragen auf:

  • Wie wird der aktuell ausgewählte Wert angezeigt?
  • Muss das Feld eine oder mehrere Auswahlmöglichkeiten unterstützen?
  • Welche Darstellung eignet sich am besten für die Liste der Auswahlmöglichkeiten?
  • Wie sollte die Suche in dieser Liste funktionieren?
  • Soll sich das Verhalten zwischen Android und iOS unterscheiden?
  • Wie rendernt man sehr lange Listen, ohne die Leistung zu beeinträchtigen?
  • Wie hält man die für Entwickler zugängliche API einfach?
  • Wie ermöglicht man Anpassungen, ohne das Komponenten in etwas Unkompliziertes zu verwandeln?

Diese Fragen von Grund auf in jeder einzelnen App zu lösen, machte keinen Sinn.

Anstatt wieder ein einmaliges, an eine bestimmte App angepasstes Komponenten zu entwickeln, machte es mehr Sinn, von Anfang an etwas Wiederverwendbares zu entwerfen.

Die zugrundeliegende Idee war einfach:

Eine Select-Komponente auf den eigenen UI-Primitiven von React Native Paper zu bauen und sie so benutzerfreundlich zu gestalten, dass andere React Native-Entwickler sie tatsächlich verwenden möchten.

Einführung in react-native-paper-select

react-native-paper-select ist eine konfigurierbare Komponente für React Native, die sowohl Einzel- als auch Mehrfachauswahl-Szenarien unterstützt.

Die erste Version baute auf den bereits von React Native Paper bereitgestellten, vertrauten Bausteinen auf, darunter:

  • TextInput
  • Checkbox
  • Dialog

Ziel war es, Entwicklern eine Auswahlfunktion zu bieten, die visuell und verhaltensmäßig mit bereits unter Verwendung des Design-Systems von React Native Paper erstellten Apps übereinstimmt.

Im Laufe der Weiterentwicklung des Pakets wurde diese anfängliche Implementierung überwunden, um zusätzliche Darstellungsstile sowie ein umfangreicheres Auswahlverhalten zu unterstützen.

Installieren des Pakets

Um damit sofort loszulegen, sind nur ein paar Schritte nötig.

npm install react-native-paper-select

Oder, falls Sie Yarn bevorzugen:

yarn add react-native-paper-select

Sobald es installiert ist, importieren Sie das Komponente wie folgt:

import { PaperSelect } from 'react-native-paper-select';

Ein einfaches Select-Feld

Um ein minimales Select-Feld zu erstellen, benötigen Sie lediglich eine Liste von Optionen sowie eine Funktion zur Handhabung der Auswahl.

Hier ist ein Beispiel:

const [selected, setSelected] = useState({
  value: '',
  label: '',
});
const options = [
  {
    _id: '1',
    value: 'React Native',
  },
  {
    _id: '2',
    value: 'Flutter',
  },
  {
    _id: '3',
    value: 'Native Android',
  },
];

Und anschließend die Darstellung der Komponente:

<PaperSelect
  label="Framework"
  value={selected.label}
  onSelection={(value) => setSelected(value)}
  arrayList={options}
  selectedArrayList={selected}
/>

Wichtig ist hier nicht, wie wenig Code dafür benötigt wird.

Vielmehr geht es darum, was dieser Code verbirgt.

Vom Standpunkt der Anwendung aus gibt es tatsächlich nur zwei Fragen, die beantwortet werden müssen:

Welche Optionen stehen zur Verfügung?

und

Was hat der Benutzer ausgewählt?

Alles, was mit der Darstellung und Interaktion zu tun hat, wird intern von dem Komponenten selbst erledigt.

Einzelauswahl gegen Mehrfachauswahl

Die Unterstützung sowohl der Einzelauswahl als auch der Mehrfachauswahl von Anfang an war eine der entscheidenden Anforderungen an diese Komponente.

Bei der Einzelauswahl ist es recht einfach, die Logik zu verstehen:

Select Framework
----------------
○ React Native
○ Flutter
○ Native Android

Mehrfachauswahl hingegen erfordert die Verwaltung zusätzlicher Zustände:

Select Technologies
-------------------
☑ React Native
☑ TypeScript
☐ Flutter
☑ Node.js

Das bedeutet, die Komponente muss sich um Folgendes kümmern:

  1. Die Auswahlzustände verfolgen
  2. Die Entfernung der Auswahl handhaben
  3. Mehrere ausgewählte Werte gleichzeitig anzeigen
  4. Die aktualisierte Auswahlmenge zurückgeben
  • Aufrechterhaltung der Synchronisation der angezeigten Benutzeroberfläche mit den zugrunde liegenden Daten
  • Das Ziel war es, all diese Komplexität innerhalb des Components selbst zu bewahren, anstatt sie auf jeden Entwickler zu übertragen, der das Paket verwendet.

    Warum React Native Paper?

    Da die umgebende Anwendung bereits auf React Native Paper setzte, war es eine logische Entscheidung, den Select-Component auf derselben Design-Plattform zu entwickeln.

    Anstatt jedes visuelle Element neu zu erfinden, konnte der Component die bereits von Paper bereitgestellten UI-Elemente wiederverwenden.

    Auf höherer Ebene sah die interne Struktur ungefähr so aus:

                    PaperSelect
                         │
              ┌──────────┴──────────┐
              │                     │
          TextInput            Selection UI
                                    │
                        ┌───────────┼───────────┐
                        │           │           │
                     Checkbox      Radio       List
    

    Diese Designentscheidung bringt tatsächliche Vorteile mit sich.

    Jede Anwendung, die bereits React Native Paper verwendet, kann diesen Select-Component einbinden, ohne einen visuellen Stil einzuführen, der mit dem Rest der Benutzeroberfläche kollidiert.

    Von Dialog zu mehreren Darstellungsstilen

    Die erste Version des Komponenten bot lediglich ein Dialogfeld zum Auswählen an.

    Die Interaktion funktionierte wie folgt:

    TextInput
        ↓
    User taps field
        ↓
    Dialog opens
        ↓
    User selects an item
        ↓
    Selected value appears in TextInput
    

    Doch mit der Weiterentwicklung des Komponenten wurde deutlich, dass ein Dialog nicht immer das richtige Muster für jeden mobilen Bildschirm ist.

    Die Anforderungen an die Benutzererfahrung unterscheiden sich stark von App zu App.

    Um dies berücksichtigen zu können, erweiterte sich der Komponenten um mehrere Darstellungsmodi:

    • Dialog
    • Bottom Sheet
    • Menü

    Durch diese Änderung kann derselbe zugrunde liegende Auswahlkomponente in völlig unterschiedlichen Interaktionskontexten eingesetzt werden, und Entwickler müssen ihre Integration nicht neu schreiben, um zwischen ihnen zu wechseln.

    Zum Beispiel:

    <PaperSelect
      presentationStyle="bottomSheet"
      ...
    />
    

    Diese Flexibilität stellte einen bedeutenden Fortschritt für die Bibliothek dar.

    Die Auswahllogik bleibt unverändert, egal für welchen Stil man sich entscheidet – nur die Darstellung für den Benutzer ändert sich.

    Umgang mit großen Listen

    Eine weniger offensichtliche Herausforderung bei Komponenten im Dropdown-Stil ist die Leistung der Liste, je größer sie wird.

    Stellen Sie sich eine Select-Komponente mit folgendem Inhalt vor:

    10 items
    

    Das ist einfach zu rendern.

    Stellen Sie sich nun eine mit folgendem Inhalt vor:

    1,000 items
    

    oder sogar:

    10,000 items
    

    Das Rendern so vieler Listeneinträge auf einmal kann die Reaktionsfähigkeit einer mobilen App beeinträchtigen.

    Um das zu vermeiden, setzt das Paket auf FlashList zur Darstellung seiner Optionenlisten.

    Das Konzept ist einfach:

    Large dataset
          ↓
    Virtualized list
          ↓
    Render what is needed
          ↓
    Better scrolling performance
    

    Leistung ist kein Problem, das man aufschieben kann, bis man etwas im großen Maßstab entwickelt.

    Jeder für die Wiederverwendung vorgesehene Komponente muss von Anfang an mit Skalierbarkeit im Blick entwickelt werden, da man selten im Voraus weiß, wie groß die an sie übergebenen Datensätze sein werden.

    Suchen

    Je mehr Auswahlmöglichkeiten vorhanden sind, desto wichtiger wird das Suchen.

    Anstatt dass die Benutzer endlos durch eine lange Liste scrollen müssen, bietet die Komponente eine suchfunktionale Möglichkeit, die Auswahl einzugrenzen.

    Der Ablauf sieht so aus:

    Search
      ↓
    Filter options
      ↓
    Select result
      ↓
    Update selection
    

    Von der Sicht des Benutzers mag es wie eine kleine Ergänzung erscheinen, doch sie hat einen großen Einfluss auf die Benutzerfreundlichkeit, sobald die Anzahl der Datensätze über einige wenige Einträge hinausgeht.

    Mehrfachauswahl mit Chips

    Die gleichzeitige Anzeige mehrerer ausgewählter Werte kann schnell unübersichtlich werden.

    Zum Beispiel ist ein Wert wie:

    React Native, TypeScript, Node.js, MongoDB
    

    schwierig zu entschlüsseln, wenn er in ein Standard-Texteingabefeld gepresst wird.

    Chips lösen dieses Problem.

    Die ausgewählten Werte können stattdessen als separate, eigenständige Blöcke dargestellt werden:

    [ React Native ] [ TypeScript ]
    [ Node.js ]      [ MongoDB ]
    

    Die Komponente unterstützt diese chipbasierte Anzeige für Szenarien mit Mehrfachauswahl und gibt den Benutzern ein viel klareres Bild davon, was sie ausgewählt haben.

    Außerdem macht es das Entfernen einzelner Auswahlmöglichkeiten deutlich intuitiver.

    Sektorielle Listen

    Eine weitere Anforderung war die Möglichkeit, zusammenhängende Optionen zu gruppieren.

    Anstelle einer langen, flachen Liste wie:

    React
    Angular
    Vue
    Node.js
    Java
    Python
    MongoDB
    PostgreSQL
    

    können die Optionen unter Überschriften organisiert werden:

    Frontend
    
    ☐ React
    ☐ Angular
    ☐ Vue
    Backend☐ Node.js
    ☐ Java
    ☐ Python
    Database☐ MongoDB
    ☐ PostgreSQL
    

    Durch diese Gruppierung sind große Optionensätze viel leichter zu überfliegen und zu verstehen.

    In Modus der Mehrfachauswahl beschleunigt es die Arbeit erheblich, wenn Benutzer eine ganze Sektion auf einmal auswählen können.

    Zum Beispiel:

    ☑ Frontend
    
        ☑ React
        ☑ Angular
        ☑ Vue
    

    Das ist besser, als jemanden zwingen zu müssen, nacheinander durch jedes Element zu tippen.

    Radio-Buttons für die Einzelauswahl

    Checkboxen sind sinnvoll, wenn mehr als eine Option ausgewählt werden kann.

    Aber bei Szenarien der Einzelauswahl vermitteln Radio-Buttons die Absicht dem Benutzer klarer.

    Deshalb bietet das Paket auch eine Variante der Auswahl-Oberfläche mit Radio-Buttons an.

    Die zugrundeliegende Idee bleibt konstant:

    Options
       ↓
    User chooses one
       ↓
    Selection state updated
    

    Nur die visuelle Darstellung ändert sich.

    Dies unterstreicht ein wichtiges Prinzip bei der Erstellung wiederverwendbarer Komponenten:

    Halten Sie die Auswahllogik getrennt von der Art und Weise, wie diese Auswahl dargestellt wird.

    TypeScript und API-Design

    Da dieses von anderen Entwicklern verwendet werden soll, ist die Struktur der API genauso wichtig wie das Aussehen der Benutzeroberfläche.

    Jemand, der das Paket nutzt, sollte nichts über die interne Funktionsweise wissen müssen.

    Idealerweise können sie rein in Bezug auf folgende Aspekte darüber nachdenken:

    Input
      ↓
    Options
      ↓
    User interaction
      ↓
    Selection
      ↓
    Callback
    

    anstatt:

    Dialog state
    Modal state
    List state
    Search state
    Checkbox state
    Rendering state
    ...
    

    Eine gut gestaltete Component-API verbirgt diese interne Komplexität vor dem Nutzer.

    Das ist eine der klarsten Erkenntnisse, die sich aus dem Entwickeln und Weiterentwickeln dieses Pakets ergeben haben.

    Open Source verändert die Art und Weise, wie man entwickelt

    Das Schreiben einer Komponente für eigene Anwendungen ist eine andere Aufgabe als das Schreiben derselben für ein breiteres Publikum von Entwicklern.

    In einer einzigen Anwendung kann das Kriterium sein:

    "Das löst meinen spezifischen Fall.

    Sobald es Open Source ist, verschiebt sich die Frage auf:

    "Würde diese API für einen Entwickler, der noch nie den Quellcode gesehen hat, sinnvoll sein?

    Diese Veränderung beeinflusst Ihre Prioritäten beim Entwickeln.

    • Konsistenz in der API
    • Dokumentation
    • Rückwärtskompatibilität
    • Edge-Cases
    • Sinnvolle Standardwerte
    • Typdefinitionen
    • Anpassungsoptionen
    • Leistung
    • Versionierung

    Was ursprünglich als kleiner, einfacher Komponente begann, kann zu etwas überraschend Komplexem werden, sobald andere Entwickler in der Produktion darauf angewiesen sind.

    Wie sich das Projekt im Laufe der Zeit entwickelt hat

    Was ursprünglich als einfache Auswahlkomponente begann, entwickelte sich allmählich zu einem umfassenderen Auswahlwerkzeugkasten.

    Ihren Wachstum können Sie ungefähr so darstellen:

    Simple Select
          ↓
    Single Selection
          ↓
    Multi Selection
          ↓
        Search
          ↓
    Large List Handling
          ↓
        Chips
          ↓
       Sections
          ↓
    Radio Selection
          ↓
    Bottom Sheet
          ↓
    Menu Presentation
    

    Jede neue Funktion behebte ein echtes Problem im Zusammenhang mit der Benutzerfreundlichkeit oder der Entwicklererfahrung.

    Das ist einer der Aspekte des Open-Source-Entwickelns, der hervorsticht.

    Wenn man Version 1 veröffentlicht, hat man selten ein klares Bild davon, wie die fertige Bibliothek letztendlich aussehen wird.

    Stattdessen verändert sich das Paket ständig, je mehr praktische Anforderungen, Nutzerfeedback und neue Anwendungsfälle auftauchen.

    Lektionen aus dem Prozess

    1. Kleine Probleme können zu wertvollen Open-Source-Projekten werden

    Das ursprüngliche Problem war keineswegs bahnbrechend.

    Einfach fehlte ein wiederverwendbarer Select-Komponent.

    Doch es besteht ein echter Unterschied zwischen der Behebung eines Problems für den eigenen Gebrauch und seiner Weiterentwicklung bis zum Punkt, an dem andere Menschen es ebenfalls nutzen können.

    Mannchmal ist dieser Unterschied genau groß genug, um ein Open-Source-Projekt zu rechtfertigen.

    2. Etwas wiederverwendbar zu machen bedeutet, es richtig abzustrahieren

    Eine gut gestaltete Komponente sollte nicht an die spezifische Anwendung gebunden sein, aus der sie hervorgegangen ist.

    Anstelle dessen muss es eine saubere, einfache Benutzeroberfläche nach außen präsentieren, während seine interne Komplexität verborgen bleibt.

    Dieses Prinzip gilt weit über die Welt von React Native hinaus.

    3. Das Komponentendesign dreht sich auch um die Benutzererfahrung

    Dass eine Komponente auf Codeebene wiederverwendbar ist, ist noch nicht alles.

    Auch das Gefühl beim Umgang damit spielt genauso eine wichtige Rolle.

    Dialoge, Bottom Sheets, Menüs, Chips, Suchfelder, Radio-Buttons und gegliederte Listen sind alle nur unterschiedliche Lösungen für dieselbe grundlegende Frage:

    Wie kann jemand am besten eine Auswahl treffen?

    4. Wiederverwendbare Komponenten müssen mit Blick auf die Leistung entwickelt werden

    Eine Komponente, die mit zehn Elementen gut funktioniert, könnte später an einem Ort mit zehntausend Elementen eingesetzt werden.

    Deshalb gehören Entscheidungen bezüglich der Darstellung in Listen und Virtualisierung bereits in die Entwurfsphase – nicht erst als Nachgedanke, wenn Leistungsprobleme in der Produktion auftauchen.

    5. Dokumentation ist ein wesentlicher Bestandteil des Pakets, kein Zusatz

    Code, der funktioniert, reicht nicht aus, um ein Paket als fertig zu bezeichnen.

    Entwickler benötigen weiterhin klare Antworten zu:

    • Wie es installiert wird
    • Wie es verwendet wird
    • Welche Eigenschaften verfügbar sind
    • Welche Form die erwarteten Daten haben sollten
    • Wie sich sein Verhalten und seine Aussehen anpassen lassen
    • Welche Funktionen tatsächlich unterstützt werden

    Gute Dokumentation schließt die Lücke zwischen dem Punkt, an dem jemand denkt:

    "I found this package."
    

    und dem Punkt, an dem er mit Sicherheit sagen kann:

    "I can use this package."
    

    Wo das Projekt von hier aus weitergeht

    Zu Beginn war das Ziel hinter react-native-paper-select bescheiden: ein Auswahlkomponente, die sich nahtlos in Apps integrieren ließ, die bereits React Native Paper verwendeten.

    Seitdem hat sich dieses Werkzeug zu einer weitaus leistungsfähigeren Lösung entwickelt, die nun mehrere Auswahlmodi, verschiedene Darstellungsstile, Suchfunktionen, aus Chip-Bausteinen bestehende Auswahlmöglichkeiten, in Abschnitte unterteilte Daten sowie eine leistungsorientierte Anzeige von Listen umfasst.

    Es gibt immer noch viel Raum für weitere Verbesserungen.

    Kein Open-Source-Projekt ist jemals wirklich abgeschlossen.

    Es tauchen ständig neue Geräte auf, React Native selbst veröffentlicht kontinuierlich Updates, die Erwartungen an das Design ändern sich, die Anforderungen an Barrierefreiheit entwickeln sich weiter, Leistungsaspekte kommen wieder ins Spiel, und Entwickler liefern ständig Feedback, das berücksichtigt werden sollte.

    Diese kontinuierliche Entwicklung ist ein Teil dessen, was die Wartung einer solchen Bibliothek wirklich reizvoll macht.

    Fazit

    Die Arbeit an react-native-paper-select hat gezeigt, dass ein Open-Source-Projekt nicht unbedingt von einer großen Vision ausgehen muss.

    Oft beginnt es mit einem kleinen, spezifischen Problem, dem man beim Erstellen von etwas anderem begegnet.

    Man löst es für sich selbst.

    Dann wird klar, dass die Lösung anderen helfen könnte, die vor dem gleichen Problem stehen.

    Deshalb wird sie weiter verfeinert.

    Man dokumentiert sie ordnungsgemäß.

    Man stellt sie der Öffentlichkeit zur Verfügung.

    Im Laufe der Zeit kann ein kleines internes Komponenten in ein Paket verwandelt werden, auf das andere Entwickler für ihre eigenen Projekte angewiesen sind.

    Das ist die Geschichte hinter react-native-paper-select.

    Falls Ihr Projekt React Native Paper verwendet und Sie ein flexibles Ein- oder Mehrfachauswahlelement benötigen, ist das Repository auf GitHub gehostet, und das Paket selbst wird auf npm veröffentlicht.

    Falls Sie das Paket nutzen, sind Feedbacks, Fehlerberichte sowie Beiträge stets willkommen.