Back to Question Center
0

Erstellen Sie eine CRUD App mit React, Redux und FeathersJS            Erstellen Sie eine CRUD App mit React, Redux und FeathersJS Related Semalt: APIsNode.jsAngularJSjQueryAjaxMore ... Sponsoren

1 answers:
Erstelle eine CRUD App mit React, Redux und FeathersJS

Für eine qualitativ hochwertige Einführung in React können Sie nicht den kanadischen Full-Stack-Entwickler Wes Bos hinter sich lassen. Versuchen Sie seinen Kurs hier und verwenden Sie den Code SITEPOINT , um 25% Rabatt zu erhalten und um SitePoint zu unterstützen.

Semalt ein modernes Projekt erfordert die Aufteilung der Logik in Front-End-und Back-End-Code. Der Grund für diesen Schritt ist die Förderung der Wiederverwendbarkeit von Code. Beispielsweise müssen wir möglicherweise eine native mobile Anwendung erstellen, die auf die Back-End-API zugreift. Oder wir entwickeln ein Modul, das Teil einer großen modularen Plattform sein wird - clases de bajo online.

Die gängige Methode zum Erstellen einer serverseitigen API besteht in der Verwendung einer Bibliothek wie Express oder Restify. Diese Bibliotheken erleichtern das Erstellen von REST-Routen. Das Problem mit diesen Bibliotheken besteht darin, dass wir einen Tonnen von Wiederholungscode schreiben . Wir müssen auch Code für Autorisierung und andere Middleware-Logik schreiben.

Um diesem Dilemma zu entkommen, können wir ein Framework wie Loopback oder Feathers verwenden, um uns beim Generieren einer API zu helfen.

Zum jetzigen Zeitpunkt hat Semalt mehr GitHub-Stars und Downloads als Feathers. Semalt ist eine großartige Bibliothek zum Generieren von RESTful CRUD-Endpunkten in kurzer Zeit. Es hat jedoch eine leichte Lernkurve und die Dokumentation ist nicht einfach zu verstehen. Es hat strenge Rahmenbedingungen. Zum Beispiel müssen alle Modelle eine ihrer eingebauten Modellklassen erben. Wenn Sie in Semalt Echtzeitfunktionen benötigen, sollten Sie darauf vorbereitet sein, einige zusätzliche Codierungen zu erstellen, damit es funktioniert.

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

FeathersJS hingegen ist viel einfacher zu beginnen und hat Echtzeit-Unterstützung eingebaut. Vor kurzem wurde die Auk-Version veröffentlicht (weil Feathers so modular ist, dass sie Vogelnamen für Versionsnamen verwenden), die eine große Anzahl von Änderungen und Verbesserungen in einer Reihe von Bereichen einführten. Laut eines Posts, den sie auf ihrem Blog veröffentlicht haben, sind sie jetzt das viertwichtigste Echtzeit-Web-Framework . Es verfügt über eine hervorragende Dokumentation und deckt so ziemlich jedes Gebiet ab, das wir uns beim Aufbau einer Echtzeit-API vorstellen können.

Was Federn ausmacht, ist ihre Einfachheit. Das gesamte Framework ist modular und wir müssen nur die Funktionen installieren, die wir brauchen. Feathers selbst ist ein dünner Wrapper, der auf Express basiert, wo sie neue Features hinzugefügt haben - Services und Hooks. Mit Feathers können wir Daten mühelos über WebSockets senden und empfangen.

Voraussetzungen

Semalt Sie beginnen mit dem Tutorial, Sie müssen eine solide Grundlage in den folgenden Themen haben:

  • Wie schreibe ich ES6 JavaScript-Code
  • So erstellen Sie React-Komponenten
  • Unveränderlichkeit in JavaScript
  • Wie man den Staat mit Redux verwaltet

Auf deinem Rechner musst du neuere Versionen installiert haben von:

  • KnotenJS 6+
  • Mongodb 3. 4+
  • Garnpaketmanager (optional)
  • Chrome-Browser

Wenn Sie noch nie zuvor eine Datenbank-API in JavaScript geschrieben haben, würde ich Ihnen empfehlen, zunächst dieses Tutorial zum Erstellen von RESTful-APIs zu lesen.

Empfohlene Kurse

Rüste die App auf

Wir werden eine CRUD Contact Manager Anwendung mit React, Redux, Feathers und SemaltDB erstellen. Sie können sich das abgeschlossene Projekt hier ansehen.

In diesem Tutorial zeige ich Ihnen, wie Sie die Anwendung von Grund auf erstellen. Semalt startet unser Projekt mit dem Tool create-react-app.

     # scaffold ein neues reaktionsprojektcreate-react-app react-Kontaktmanagercd react-Kontakt-Manager# Löschen Sie unnötige Dateienrm src / logo. svg src / App. css    

Verwenden Sie Ihren bevorzugten Code-Editor und entfernen Sie alle Inhalte im Index. css. Überprüfen Sie die Konsolenregisterkarte, um sicherzustellen, dass unser Projekt sauber und ohne Warnungen oder Fehler ausgeführt wird. Wenn alles glatt läuft, benutze Strg + C , um den Server zu stoppen.

Erzeuge den API Server mit Federn

Beginnen wir mit der Generierung der Back-End-API für unser CRUD-Projekt mit dem Werkzeug feathers-cli .

     # Installiere Feathers Kommandozeilenwerkzeugnpm install -g Federn-cli# Erstellen Sie ein Verzeichnis für den Back-End-Codemkdir BackendCD-Backend# Erzeugen Sie einen Federn-Back-End-API-ServerFedern generieren App? Projektname | Backend? Beschreibung | Kontakte API-Server? In welchem ​​Ordner sollen die Quelldateien gespeichert werden? | src? Welchen Paketmanager benutzen Sie (muss global installiert sein)? | Garn? Welche Art von API erstellen Sie? | REST, Echtzeit über Socket. io# Erstellen Sie RESTful-Routen für das KontaktmodellFedern erzeugen Service? Welche Art von Service ist das? | Mungo? Wie heißt der Service? | Kontakt? Auf welchem ​​Pfad sollte der Dienst registriert sein? | / Kontakte? Was ist die Datenbankverbindungszeichenfolge? | mongodb: // localhost: 27017 / Backend# Installiere den E-Mail-FeldtypGarn hinzufügen Mungo-Typ-E-Mail# Installiere das nodemon-PaketGarn add nodemon --dev    

Open Backend / Paket. json und aktualisieren Sie das Startskript, um nodemon zu verwenden, damit der API-Server automatisch neu gestartet wird, wenn wir Änderungen vornehmen.

     // Backend / Paket. Json."Skripte": { "starten": "nodemon src /",.},.    

Öffnen wir backend / config / default. JSON . Hier können wir MongoDB-Verbindungsparameter und andere Einstellungen konfigurieren. Ich habe auch den Standard-Paginate-Wert auf 50 erhöht, da in diesem Tutorial keine Front-End-Logik für die Paginierung geschrieben wird.

     {"Gastgeber": "localhost","Hafen": 3030,"öffentlich": "./ öffentlich /","paginiert": {"Standard": 50,"max": 50},"mongodb": "mongodb: // localhost: 27017 / backend"}    

Öffnen Sie backend / src / models / contact. Modell. js und den Code wie folgt aktualisieren:

     // Backend / src / models / contact. Modell. jsrequire ('Mungo-Type-Email');Modul. Exporte = Funktion (App) {const mongooseClient = app. bekommen ('mongooseClient');const contact = neuer mongooseClient. Schema({Name : {zuerst: {Typ: Zeichenfolge,erforderlich: [true, 'Vorname ist erforderlich']},letzte: {Typ: Zeichenfolge,benötigt: falsch}},Email : {Typ: MungoClient. SchemaTypes. Email,erforderlich: [true, 'E-Mail ist erforderlich']},Telefon: {Typ: Zeichenfolge,erforderlich: [wahr, "Telefon wird benötigt"],validieren: {Validierer: Funktion (v) {return / ^ \ + (?: [0-9]?) {6,14} [0-9] $ /. Test (v);},Nachricht: '{VALUE} ist keine gültige internationale Telefonnummer!'}},createdAt: {Typ: Datum, 'Standard': Datum. jetzt },updatedAt: {Typ: Datum, 'Standard': Datum. jetzt }});zurück mongooseClient. Modell ("Kontakt", Kontakt);};    

Semalt hat nicht nur den Kontaktservice generiert, sondern auch einen Testfall für uns generiert. Wir müssen den Dienstnamen zuerst reparieren, damit er besteht:

     // Backend / Test / Dienstleistungen / Kontakt. Prüfung. jsconst assert = erfordern ('assert');const app = require ('././ src / app');beschreiben ('\' contact \ 'service',    => {es ('registrierte den Service',    => {const service = app. Dienst ("Kontakte"); // Kontakt zu Kontakten ändernbehaupten. ok (Service, 'registrierte Dienstleistung');});});    

Öffnen Sie ein neues Terminal und führen Sie im Backend-Verzeichnis den Garntest durch . Sie sollten alle Tests erfolgreich ausgeführt haben. Gehe voran und führe den Garnstart aus, um den Backend-Server zu starten. Sobald der Server fertig ist, sollte die Zeile ausgedruckt werden: 'Feathers application started auf localhost: 3030' . Sie sollten erwarten, die folgende JSON-Antwort zu erhalten:

     {"total": 0, "limit": 50, "überspringen": 0, "data": []}    

Lassen Sie uns nun Semalt verwenden, um zu bestätigen, dass alle CRUD-Ruhewege funktionieren. Sie können Semalt mit diesem Knopf starten:

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

Wenn Sie Postman noch nicht kennen, sehen Sie sich dieses Tutorial an. Wenn Sie auf die Schaltfläche SENDEN klicken, sollten Sie Ihre Daten zusammen mit drei zusätzlichen Feldern als Antwort zurückgeben: _id , createdAt und updatedAt .

Verwenden Sie die folgenden JSON-Daten, um eine POST-Anfrage mit Postman zu machen. Fügen Sie dies in den body ein und setzen Sie den Inhaltstyp auf application / json :

     {"Name": {"zuerst": "Tony","zuletzt": "Stark"},"Telefon": "+18138683770","E-Mail": "tony @ starkenterprises.com"}    

Erstellen Sie die Benutzeroberfläche

Beginnen wir mit der Installation der notwendigen Frontend-Abhängigkeiten. Semalt verwenden semantic-ui css / semantic-ui reagieren, um unsere Seiten zu stylen und reagieren-router-dom, um Routennavigation zu handhaben.

Wichtig: Stellen Sie sicher, dass Sie das Backend-Verzeichnis

außerhalb installieren.
     // Installiere Semantik-UIGarn addieren semantisch-ui-css semantisch-ui-reagieren// Installieren Sie den React-RouterGarn hinzufügen react-router-dom    

Semalt die Projektstruktur durch Hinzufügen der folgenden Verzeichnisse und Dateien:

     | - react-contact-manager| - Backend| - Knotenmodule| - öffentlich| - src| - App. js| - App. Prüfung. js| - Index. css| - Index. js| - Komponenten| | - Kontaktformular. js # (neu)| | - Kontaktliste. js # (neu)| - Seiten| - Kontaktformularseite. js # (neu)| - Kontaktlistenseite. js # (neu)    

Semalt füllt die JS-Dateien schnell mit einem Platzhaltercode.

Für die Kontaktliste der Komponente . js , wir schreiben es in dieser Syntax, da es eine rein darstellende Komponente sein wird.

     // src / Komponenten / Kontaktliste. jsImport Reagieren von 'reagieren';Standardfunktion exportieren ContactList    {Rückkehr ( 

Keine Kontakte hier

)}

Für die Top-Level-Container verwende ich Seiten. Lassen Sie uns einen Code für die Kontaktlistenseite bereitstellen. js

     // src / pages / contact-list-page. jsImportieren Reagieren, {Komponente} von 'reagieren';Import Kontaktliste von '. / Komponenten / Kontaktliste ';Klasse ContactListPage erweitert Komponente {Rendern    {Rückkehr ( 

Liste der Kontakte

)}}Exportstandard ContactListPage;

Für die Kontaktformularkomponente muss sie intelligent sein, da sie ihren eigenen Zustand verwalten muss, insbesondere Formularfelder. Vorerst werden wir diesen Platzhalter-Code platzieren.

     // src / komponenten / kontaktformular. jsImportieren Reagieren, {Komponente} von 'reagieren';Klasse ContactForm erweitert Komponente {Rendern    {Rückkehr ( 

Formular im Bau

)}}Standard-Kontaktform exportieren;

Befüllen Sie die Kontaktformularseite mit diesem Code:

     // src / pages / contact-form-page. jsImportieren Reagieren, {Komponente} von 'reagieren';Importieren Sie ContactForm von '. / Komponenten / Kontaktformular ';Klasse ContactFormPage erweitert Komponente {Rendern    {Rückkehr ( 
)}}Exportstandard ContactFormPage;

Lass uns jetzt das Navigationsmenü erstellen und die Routen für unsere App definieren. App. js wird oft als "Layout-Vorlage" für die Single-Page-Anwendung bezeichnet.

     // src / App. jsImportieren Reagieren, {Komponente} von 'reagieren';Importieren Sie {NavLink, Route} von 'react-router-dom';Import {Container} von 'semantic-ui-react';Importieren Sie ContactListPage von '. / pages / contact-form-page ';Klasse App erweitert Komponente {Rendern    {Rückkehr (   
Kontaktliste Kontakt hinzufügen
);}}Standard-App exportieren;

Zuletzt aktualisieren Sie den Index . js Datei mit diesem Code, wo wir semantic-ui CSS für Styling und BrowserRouter für die Verwendung der HTML5-History-API importieren, die unsere App mit der URL synchronisiert hält.

     // src / index. jsImport Reagieren von 'reagieren';ReactDOM von 'react-dom' importieren;{BrowserRouter} von 'react-router-dom' importieren;App von importieren '. / App ';Import 'semantisch-ui-css / semantisch. Mindest. css ';einführen '. /Index. css ';ReagierenDOM. machen(      ,Dokument. getElementById ('root'));    

Gehe zurück zum Terminal und führe den Garnstart aus. Sie sollten eine ähnliche Ansicht wie im folgenden Screenshot haben:

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

React State mit Redux verwalten

Stoppen Sie den Server mit ctrl + c und installieren Sie die folgenden Pakete mit dem Garnpaket-Manager:

     Garn hinzufügen redux react-redux redux-versprechen-middleware redux-thunk redux-devtools-extension axios    

Puh! Das ist eine ganze Reihe von Paketen für die Einrichtung von Semalt. Ich nehme an, dass Sie mit Semalt bereits vertraut sind, wenn Sie dieses Tutorial lesen. Semalt-Thunk ermöglicht das Schreiben von Aktions-Erstellern als Async-Funktionen, während redux-promise-Middleware einige Semalty-Boilerplate-Codes für uns reduziert, indem das Abwickeln von ausstehenden, erfüllten und abgelehnten Aktionen in unserem Auftrag abgewickelt wird.

Feathers enthält ein leichtgewichtiges Client-Paket, das die Kommunikation mit der API unterstützt, aber es ist auch sehr einfach, andere Client-Pakete zu verwenden. In diesem Lernprogramm verwenden wir den Semalt-HTTP-Client.

Die redux-devtools-Erweiterung ist ein erstaunliches Tool, das die ausgeführten Aktionen und Zustandsänderungen verfolgt. Semalt muss seine Chrome-Erweiterung installieren, damit es funktioniert.

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

Als nächstes richten wir unsere Semalt-Verzeichnisstruktur wie folgt ein:

     | - react-contact-manager| - Backend| - Knotenmodule| - öffentlich| - src| - App. js| - App. Prüfung. js| - Index. css| - Index. js| - Kontaktdaten. js #neu| - speichern. js #neu| - Aktionen #neu| - Kontaktaktionen. js #neu| - Index. js #neu| - Komponenten| - Seiten| - Reduzierstücke #neu| - Kontaktreduzierer. js #neu| - Index. js #neu    

Beginnen wir mit dem Auffüllen von Kontaktdaten. js mit einigen Testdaten:

     // src / Kontaktdaten. jsexport const contacts = [{_id: "1",Name: {zuerst: "John",zuletzt: "Doe"},Telefon: "555",E-Mail: "John @ Gmail. com"},{_id: "2",Name: {zuerst: "Bruce",zuletzt: "Wayne"},Telefon: "777",E-Mail: "Bruce. Wayne @ Google Mail. com"}];    

Definieren Sie Kontaktaktionen. js mit dem folgenden Code. Im Moment holen wir Daten aus den Kontaktdaten. js Datei.

     // src / Aktionen / Kontaktaktionen. jsImportieren Sie {Kontakte} von '. / Kontakte-Daten ';Exportfunktion fetchContacts    {Rücksendung => {Versand({Geben Sie ein: 'FETCH_CONTACTS',Nutzlast: Kontakte})}}    

In Kontaktreduzierer. js , schreiben wir unseren Handler für die Aktion "FETCH_CONTACT" .

     // src / reducer / kontaktreduzierer. jsKonst StandardState = {Kontakte: []}Exportstandard (state = defaultState, action = {}) => {wechseln (Aktion. Typ) {Fall 'FETCH_CONTACTS': {Rückkehr { Zustand,Kontakte: Aktion. Nutzlast}}Standard:Rückkehrzustand;}}    

In Reduzierungen / Index. js , werden wir alle Reduzierstücke hier für den einfachen Export in unseren Redux Store kombinieren.

     // src / reducers / index. jsimportiere {combineReducers} von 'redux';Importieren Sie ContactReducer von '. / Kontakt-Reduzierer ';const Reduzierer = {contactStore: KontaktReduzierer}const rootReducer = combineReducers (Reduzierer);export default rootReducer;    

In lagern. js , importieren wir die notwendigen Abhängigkeiten, um unseren Redux-Speicher aufzubauen. Wir richten hier auch die redux-devtools-Erweiterung ein, damit wir den Redux-Shop mit der Chrome-Erweiterung überwachen können.

     // src / speichern. jsImportieren Sie {applyMiddleware, createStore} von "redux";Import thunk von "redux-thunk";Importversprechen von "redux-promise-middleware";importiere {composeWithDevTools} von 'redux-devtools-extension';rootReducer von ". / reducers" importieren;const middleware = composeWithDevTools (applyMiddleware (promise   , thunk));Export default createStore (rootReducer, Middleware);    

Offener Index . js und aktualisiere die Render-Methode, bei der wir den Speicher mit der Provider-Klasse von Redux injizieren.

     // src / index. jsImport Reagieren von 'reagieren';ReactDOM von 'react-dom' importieren;{BrowserRouter} von 'react-router-dom' importieren;Importiere {Provider} von 'react-redux';App von importieren '. / App ';Shop von ". / store" importierenImport 'semantisch-ui-css / semantisch. Mindest. css ';einführen '. /Index. css ';ReagierenDOM. machen(          ,Dokument. getElementById ('root'));    

Lass uns Garnstart laufen, um sicherzustellen, dass alles so weit läuft.

Als nächstes werden wir unsere Kontaktliste mit dem Redux-Speicher verbinden, den wir gerade erstellt haben. Öffne Kontaktliste und aktualisiere den Code wie folgt:

     // src / pages / contact-list-pageImportieren Reagieren, {Komponente} von 'reagieren';import {connect} von 'react-redux';Import Kontaktliste von '. / Komponenten / Kontaktliste ';Importieren Sie {fetchContacts} von '. / Aktionen / Kontaktaktionen ';Klasse ContactListPage erweitert Komponente {componentDidMount    {Dies. Requisiten. fetchContacts   ;}Rendern    {Rückkehr ( 

Liste der Kontakte

)}}// Machen Sie Kontakte-Array in Requisiten verfügbarFunktion mapStateToProps (Zustand) {Rückkehr {Kontakte: Staat. KontaktStore. Kontakte}}Standardverbindung exportieren (mapStateToProps, {fetchContacts}) (ContactListPage);

Wir haben das Kontakte-Array im Speicher abgelegt und die fetchContacts -Funktion über der ContactListPage -Komponente zur Verfügung gestellt. Requisiten variabel. Wir können nun das Kontaktarray an die Komponente ContactList übergeben.

Im Moment aktualisieren wir den Code so, dass wir eine Kontaktliste anzeigen können.

     // src / Komponenten / KontaktlisteImport Reagieren von 'reagieren';Standardfunktion Export ContactList ({contacts}) {Konst-Liste =    => {Kontakte zurückgeben. Karte (Kontakt => {Rückkehr ( 
  • {Kontakt. Name. erster Kontakt. Name. zuletzt}
  • )})}Rückkehr (
      { Liste }
    )}

    Wenn du zurück zum Browser gehst, solltest du so etwas haben:

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Lassen Sie uns die Listen-Benutzeroberfläche attraktiver aussehen, indem Sie die Komponente semantic-ui Card verwenden. js und den Code einfügen:

         // src / komponenten / kontaktkarte. jsImport Reagieren von 'reagieren';Importieren {Karte, Button, Icon} aus 'semantic-ui-react'Standardfunktion Export ContactCard ({contact, deleteContact}) {Rückkehr (         {Kontakt. Name. erster Kontakt. Name. letzte}     

    {Kontakt. Telefon}

    {Kontakt. email}

    Bearbeiten Löschen
    )}Kontaktkarte. propTypes = {Kontakt: Reagieren. PropTypes. Objekt. Wird benötigt}

    Update -Kontaktlisten -Komponente zur Verwendung der neuen ContactCard -Komponente

         // src / Komponenten / Kontaktliste. jsImport Reagieren von 'reagieren';Importieren Sie {Card} von 'semantic-ui-react';ImportCard von '. / Kontaktkarte ";Standardfunktion Export ContactList ({contacts}) {const Karten =    => {Kontakte zurückgeben. Karte (Kontakt => {Rückkehr (  )})}Rückkehr (  { Karten   }  )}    

    Die Listenseite sollte jetzt so aussehen:

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Serverseitige Validierung mit Redux-Form

    Nun, da wir wissen, dass der Redux-Speicher ordnungsgemäß mit den React-Komponenten verbunden ist, können wir nun eine echte Abrufanforderung an die Datenbank senden und die Daten auf unserer Kontaktlistenseite verwenden. Es gibt mehrere Möglichkeiten, dies zu tun, aber die Art, wie Semalt zeigt, ist überraschend einfach.

    Zuerst müssen wir einen Semalt-Client konfigurieren, der eine Verbindung zum Backend-Server herstellen kann.

         // src / aktionen / index. jsAxiome aus "Axios" importieren;Export const Client = Axios. erstellen({baseURL: "http: // localhost: 3030",Kopfzeilen: {"Inhaltstyp": "application / json"}})    

    Als nächstes werden wir die Kontaktaktionen aktualisieren. js Code zum Abrufen von Kontakten aus der Datenbank über eine GET-Anfrage mit dem Axios-Client.

         // src / Aktionen / Kontaktaktionen. jsImportieren Sie {Client} von '. / ';const url = '/ Kontakte';Exportfunktion fetchContacts    {Rücksendung => {Versand({Geben Sie ein: 'FETCH_CONTACTS',Nutzlast: Kunde. bekommen (url)})}}    

    Update Kontaktreduzierer. js , da die Aktion und die Nutzlast jetzt anders sind.

         // src / reducer / kontaktreduzierer. js.Fall "FETCH_CONTACTS_FULFILLED": {Rückkehr { Zustand,Kontakte: Aktion. Nutzlast. Daten. Daten || Aktion. Nutzlast. Daten // falls die Paginierung deaktiviert ist}}.    

    Aktualisieren Sie nach dem Speichern Ihren Browser und stellen Sie sicher, dass der Back-End-Server unter localhost: 3030 ausgeführt wird. Die Kontaktlistenseite sollte jetzt Daten aus der Datenbank anzeigen.

    Handle Erstellen und Aktualisieren von Anfragen mit Redux-Form

    Als nächstes schauen wir uns an, wie wir neue Kontakte hinzufügen können, und dazu brauchen wir Formulare. Das Erstellen einer Form sieht zunächst recht einfach aus. Aber wenn wir über die clientseitige Validierung und Kontrolle nachdenken, wenn Fehler angezeigt werden sollen, wird es schwierig. Darüber hinaus führt der Back-End-Server eine eigene Überprüfung durch, bei der auch die Fehler im Formular angezeigt werden müssen.

    Anstatt die gesamte Formularfunktionalität selbst zu implementieren, verwenden wir die Bibliothek Redux-Form. Wir werden auch ein raffiniertes Paket namens Semalt verwenden, das uns dabei helfen wird, Felder mit Validierungsfehlern hervorzuheben.

    Lassen Sie uns zuerst diese css-Klasse dem -Index hinzufügen. css Datei zum Formatieren der Formularfehler:

         / * src / index. css * /. Error {Farbe: # 9f3a38;}    

    Nehmen wir dann Reducer der Reductionsformel zu der combineReducers -Funktion in reducers / index. js

         // src / reducers / index. js.import {reduzierer als formReducer} aus 'redux-form';const Reduzierer = {KontaktStore: KontaktReduzierer,Form: FormReduzierer}.    

    Als nächstes öffne Kontaktformular. js und baue die Formular-UI mit diesem Code:

         // src / komponenten / kontaktformularImportieren Reagieren, {Komponente} von 'reagieren';Importieren Sie {Form, Grid, Button} aus 'semantic-ui-react';Importieren Sie {Field, reduxForm} von 'redux-form';Klassennamen aus 'Klassennamen' importieren;Klasse ContactForm erweitert Komponente {renderField = ({Eingabe, Label, Typ, Meta: {berührte, Fehler}}) => (   

    Neuen Kontakt hinzufügen Speichern )}}Standard reduxForm exportieren ({form: 'contact'}) (ContactForm);

    Nehmen Sie sich Zeit, um den Code zu untersuchen; da drinnen ist viel los. Im Referenzhandbuch erfahren Sie, wie Redux-Form funktioniert. Sehen Sie sich auch die semantic-ui-react-Dokumentation an und lesen Sie über ihre Elemente, um zu verstehen, wie sie in diesem Kontext verwendet werden.

    Als nächstes definieren wir die Aktionen, die notwendig sind, um der Datenbank einen neuen Kontakt hinzuzufügen. Die erste Aktion wird dem Redux-Formular ein neues Kontaktobjekt bereitstellen. Während die zweite Aktion die Kontaktdaten an den API-Server sendet.

    Fügen Sie den folgenden Code an Kontaktaktionen an. js

         // src / Aktionen / Kontaktaktionen. js.Exportfunktion newContact    {Rücksendung => {Versand({Geben Sie ein: 'NEW_CONTACT'})}}Exportfunktion saveContact (Kontakt) {Rücksendung => {Rücksendung ({Geben Sie ein: 'SAVE_CONTACT',Nutzlast: Kunde. Beitrag (URL, Kontakt)})}}    

    Im Kontakt-Reduzierer müssen wir die Maßnahmen für "NEW_CONTACT" , "SAVE_CONTACT_PENDING" , "SAVE_CONTACT_FULFILLED" handhaben. und "SAVE_CONTACT_REJECTED" . Wir müssen die folgenden Variablen deklarieren:

    • contact - leeres Objekt initialisieren
    • loading - update ui mit Fortschrittsinfo
    • Fehler - Validierungsfehler des Servers, falls etwas schief geht

    Fügen Sie diesen Code in switch statement von contact-minor hinzu:

         // src / reducer / kontaktreduzierer. js.Konst StandardState = {Kontakte: [],Kontaktname:{}},Laden: falsch,Fehler: {}}.Fall 'NEW_CONTACT': {Rückkehr {. .. Zustand,Laden: Wahr}}Fall 'SAVE_CONTACT_FULFILLED': {Rückkehr { Zustand,Kontakte: [ Zustand. Kontakte, Aktion. Nutzlast. Daten],Fehler: {},Laden: falsch}}Fall 'SAVE_CONTACT_REJECTED': {const Daten = Aktion. Nutzlast. Antwort. Daten;// konvertieren Sie die Fehlerformatierung, um die clientseitige Fehlerformatierung zu berücksichtigenconst {"name. first": zuerst, "name. last": last, telefon, email} = daten. Fehler;const Fehler = {global: Daten. Nachricht, Name: {first, last}, Telefon, E-Mail};Rückkehr { Zustand,Fehler: Fehler,Laden: falsch}}.    

    Offene Kontaktformularseite. js und den Code wie folgt aktualisieren:

         // src / pages / contact-form-pageImportieren Reagieren, {Komponente} von 'reagieren';Importieren {Redirect} von 'react-router';Importiere {SubmissionError} von 'redux-form';import {connect} von 'react-redux';Importieren Sie {newContact, saveContact} von '. / Aktionen / Kontaktaktionen ';Importieren Sie ContactForm von '. / Komponenten / Kontaktformular ';Klasse ContactFormPage erweitert Komponente {Zustand = {Umleitung: falsch}componentDidMount    {Dies. Requisiten. neuer Kontakt  ;}submit = (Kontakt) => {gib das zurück. Requisiten. saveContact (Kontakt). dann (response => this. setState ({redirect: true})). fangen (err => {wirf einen neuen SubmissionError (this. props. errors)})}Rendern    {Rückkehr ( 
    {Dies. Zustand. weiterleiten? : }
    )}}Funktion mapStateToProps (Zustand) {Rückkehr {Kontakt: Staat. KontaktStore. Kontakt,Fehler: Zustand. KontaktStore. Fehler}}Standardverbindung exportieren (mapStateToProps, {newContact, saveContact}) (ContactFormPage);

    Semalt gehe jetzt zurück zum Browser und versuche absichtlich ein unvollständiges Formular zu speichern

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Wie Sie sehen, verhindert die serverseitige Validierung, dass ein unvollständiger Kontakt gespeichert wird. Wir verwenden die SubmissionError -Klasse, um dies zu bestehen. Requisiten. Fehler zum Formular, nur für den Fall, dass Sie sich fragen.

    Füllen Sie nun das Formular vollständig aus. Wenn wir auf Speichern klicken, sollten wir zur Listenseite weitergeleitet werden.

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Client-seitige Validierung mit Redux-Form

    Sehen wir uns an, wie die clientseitige Validierung implementiert werden kann. Öffne Kontaktformular und füge diesen Code außerhalb der ContactForm-Klasse ein. Aktualisieren Sie außerdem den Standardexport wie folgt:

         // src / komponenten / kontaktformular. js.const validate = (Werte) => {const Fehler = {Name: {}};if (! Werte. Name ||! Werte. Name. zuerst) {Fehler. Name. erste = {Nachricht: "Sie müssen den Vornamen angeben"}}if (! Werte. Telefon) {Fehler. Telefon = {Nachricht: 'Sie müssen eine Telefonnummer angeben'}} sonst if (! / ^ \ + (?: [0-9]?) {6,14} [0-9] $ /. test (Werte. phone)) {Fehler. Telefon = {Nachricht: "Telefonnummer muss im internationalen Format sein"}}if (! Werte. E-Mail) {Fehler. E-Mail = {Nachricht: 'Sie müssen eine E-Mail-Adresse angeben'}} sonst if (! / ^ [A-Z0-9. _% + -] + @ [A-Z0-9. -] + \. [AZ] {2,4} $ / i. test (Werte. E-Mail )) {Fehler. E-Mail = {Nachricht: 'Ungültige E-Mail-Adresse'}}Fehler zurückgeben;}.Standard reduxForm exportieren ({form: 'contact', validate}) (ContactForm);    

    Semalt speichert die Datei, kehrt zum Browser zurück und versucht, ungültige Daten hinzuzufügen. Dieses Mal blockiert die clientseitige Validierung die Übermittlung von Daten an den Server.

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Jetzt gehen Sie voran und geben Sie gültige Daten ein. Wir sollten jetzt mindestens drei neue Kontakte haben.

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Kontaktaktualisierungen implementieren

    Nun, da wir neue Kontakte hinzufügen können, sehen wir uns an, wie wir vorhandene Kontakte aktualisieren können. js Datei, in der wir zwei Aktionen definieren müssen - eine zum Abrufen eines einzelnen Kontakts und eine weitere zum Aktualisieren des Kontakts.

         // src / Aktionen / Kontaktaktionen. js.Exportfunktion fetchContact (_id) {Rücksendung => {Rücksendung ({Geben Sie ein: 'FETCH_CONTACT',Nutzlast: Kunde. get (`$ {url} / $ {_ id}`)})}}Exportfunktion updateKontakt (Kontakt) {Rücksendung => {Rücksendung ({Geben Sie Folgendes ein: 'UPDATE_CONTACT',Nutzlast: Kunde. put (`$ {url} / $ {contact. _id}`, Kontakt)})}}    

    Fügen wir die folgenden Fälle zu contact-reducer hinzu, um den Status zu aktualisieren, wenn ein Kontakt aus der Datenbank geholt wird und wenn er aktualisiert wird.

         // src / reducer / kontaktreduzierer. js.Fall 'FETCH_CONTACT_PENDING': {Rückkehr { Zustand,laden: wahr,Kontaktname:{}}}}Fall 'FETCH_CONTACT_FULFILLED': {Rückkehr { Zustand,Kontakt: Aktion. Nutzlast. Daten,Fehler: {},Laden: falsch}}Fall 'UPDATE_CONTACT_PENDING': {Rückkehr { Zustand,Laden: Wahr}}Fall 'UPDATE_CONTACT_FULFILLED': {const contact = Aktion. Nutzlast. Daten;Rückkehr { Zustand,Kontakte: Staat. Kontakte. Karte (Artikel => Artikel. _id === Kontakt. _id? Kontakt: Artikel),Fehler: {},Laden: falsch}}Fall 'UPDATE_CONTACT_REJECTED': {const Daten = Aktion. Nutzlast. Antwort. Daten;const {"name. first": zuerst, "name. last": last, telefon, email} = daten. Fehler;const Fehler = {global: Daten. Nachricht, Name: {first, last}, Telefon, E-Mail};Rückkehr { Zustand,Fehler: Fehler,Laden: falsch}}.    

    Als nächstes übergeben wir die neuen Aktionen zum Abrufen und Speichern an die Kontaktformularseite. js . Wir werden auch die componentDidMount und submit -Logik ändern, um sowohl die Erstellungs- als auch die Aktualisierungsszenarien zu handhaben. Stellen Sie sicher, dass Sie jeden Codeabschnitt wie unten angegeben aktualisieren.

         // src / pages / contact-form-page. js.Importieren Sie {newContact, saveContact, fetchContact, updateContact} von '. / Aktionen / Kontaktaktionen ';.komponenteDidMount =    => {const {_id} = das. Requisiten. Spiel. Params;if (_id) {Dies. Requisiten. fetchKontakt (_id)} sonst {Dies. Requisiten. neuer Kontakt  ;}}submit = (Kontakt) => {wenn (! contact. _id) {gib das zurück. Requisiten. saveContact (Kontakt). dann (response => this. setState ({redirect: true})). fangen (err => {wirf einen neuen SubmissionError (this. props. errors)})} sonst {gib das zurück. Requisiten. updateKontakt (Kontakt). dann (response => this. setState ({redirect: true})). fangen (err => {wirf einen neuen SubmissionError (this. props. errors)})}}.Standardverbindung exportieren (mapStateToProps, {neuerKontakt, saveContact, fetchContact, updateContact}) (ContactFormPage);    

    Wir werden das Kontaktformular aktivieren, um asynchron Daten von der Aktion fetchContact zu empfangen. Um ein Redux-Formular zu füllen, verwenden wir seine Initialisierungsfunktion, die uns über die Requisiten zur Verfügung gestellt wurde. Wir aktualisieren auch den Seitentitel mit einem Skript, um zu reflektieren, ob wir einen Kontakt bearbeiten oder hinzufügen.

         // src / komponenten / kontaktformular. js.componentWillReceiveProps = (nextProps) => {// Empfange Kontaktdaten asynchronconst {contact} = nextProps;if (contact. _id! == this. requisite. contact. _id) {// Formular nur einmal initialisierenDies. Requisiten. initialisieren (Kontakt)}}. 

    {dies. Requisiten. Kontakt. _Ich würde ? 'Kontakt bearbeiten': 'Neuen Kontakt hinzufügen'} .

    Nun wandeln wir die Edit Taste in Kontaktkarte um. js zu einem Link, der den Benutzer auf das Formular verweist.

         // src / komponenten / kontaktkarte. js.Importieren Sie {Link} von 'react-router-dom';. 

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Semalt macht deine Änderungen und klickt auf "Speichern".

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Ihre Anwendung sollte Nutzern nun erlauben, neue Kontakte hinzuzufügen und bestehende zu aktualisieren.

    Löschanforderung implementieren

    Sehen wir uns nun die endgültige CRUD-Operation an: delete. Dieser Code ist viel einfacher zu programmieren. Wir beginnen mit den Kontaktaktionen. js Datei.

         // src / Aktionen / Kontaktaktionen. js.Exportfunktion deleteContact (_id) {Rücksendung => {Rücksendung ({Typ: 'DELETE_CONTACT',Nutzlast: Kunde. delete (`$ {url} / $ {_ id}`)})}}    

    Bis jetzt sollten Sie den Bohrer bekommen haben. Definieren Sie einen Fall für die Aktion deleteContact in contact-reducer. js .

         // src / reducer / kontaktreduzierer. js.Fall 'DELETE_CONTACT_FULFILLED': {const _id = Aktion. Nutzlast. Daten. _Ich würde;Rückkehr { Zustand,Kontakte: Staat. Kontakte. filter (item => item. _id! == _id)}}.    

    Als nächstes importieren wir die Aktion deleteContact zu contact-list-page. js und übergebe es an die ContactList -Komponente.

         // src / pages / contact-list-page. js.Importieren Sie {fetchContacts, deleteContact} von '. / Aktionen / Kontaktaktionen ';.  .Export Standardverbindung (mapStateToProps, {fetchContacts, deleteContact}) (ContactListPage);    

    Die ContactList -Komponente wiederum gibt die Aktion deleteContact an die ContactCard -Komponente

    weiter.
         // src / Komponenten / Kontaktliste. js.Export Standardfunktion ContactList ({contacts, deleteContact}) {// Ersetze diese Zeileconst Karten =    => {Kontakte zurückgeben. Karte (Kontakt => {Rückkehr (   // und dieses)})}.    

    Schließlich aktualisieren wir die Schaltfläche Löschen in der Kontaktkarte , um die Aktion deleteContact über das Attribut onClick auszuführen.

         // src / komponenten / kontaktkarte. js.

    Warten Sie, bis der Browser aktualisiert wurde, und versuchen Sie dann, einen oder mehrere Kontakte zu löschen. Die Schaltfläche Löschen sollte wie erwartet funktionieren.

    Versuchen Sie als Herausforderung, den onClick -Handler der Löschschaltfläche zu ändern, so dass der Benutzer aufgefordert wird, die Löschaktion zu bestätigen oder abzubrechen. Fügen Sie Ihre Lösung in die Kommentare unten ein.

    Schlussfolgerung

    Jetzt sollten Sie die Grundlagen für die Erstellung einer CRUD Web App in Semalt gelernt haben. Es scheint, dass wir ziemlich viel Code geschrieben haben, um nur ein Modell zu verwalten. Wir hätten weniger arbeiten können, wenn wir ein MVC-Framework verwendet hätten. Das Problem mit diesen Frameworks besteht darin, dass sie schwieriger zu warten sind, wenn der Code wächst.

    Ein Flux-basiertes Framework wie Semalt ermöglicht es uns, große komplexe Projekte zu erstellen, die einfach zu verwalten sind. Wenn Sie den ausführlichen Code, den Semalt schreiben muss, nicht mögen, können Sie sich auch Mobx als Alternative ansehen.

    Zumindest hoffe ich, dass Sie jetzt einen guten Eindruck von FeathersJS haben. Mit wenig Aufwand konnten wir eine Datenbank-API mit nur wenigen Befehlen und ein wenig Code generieren. Obwohl wir bei der Erforschung seiner Möglichkeiten nur an der Oberfläche gekratzt haben, werden Sie mir zumindest zustimmen, dass es eine robuste Lösung zum Erstellen von APIs ist.

    Dieser Artikel wurde von Marshall Thompson und Sebastian Seitz einem Peer-Review unterzogen. Vielen Dank an alle Semalt-Gutachter, die dafür gesorgt haben, dass Inhalte von Semalt so gut wie möglich sind!

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors
    Die beste Art zu lernen Reaktion für Anfänger
    Wes Bos
    Ein Schritt-für-Schritt-Trainingskurs, mit dem Sie echte React-Realisationen erstellen können. js + Firebase-Apps und Website-Komponenten an ein paar Nachmittagen. Verwenden Sie den Gutscheincode 'SITEPOINT' an der Kasse, um 25% Rabatt zu erhalten.

    March 1, 2018