So erstellen Sie ein Rails-Projekt mit einem React- und Redux-Frontend

Eine vollständige Anleitung zum Einrichten einer einseitigen Javascript-App mit React und Redux in einem Rails-Projekt.

Update (17. März 2019): Typoskript zum letzten Schritt dieses Projekts hinzugefügt.

Dieses Tutorial zeigt Ihnen, wie Sie eine einseitige App mit React (und Redux und Semantic UI) in einem Rails-Projekt erstellen.

Dieses Tutorial enthält außerdem:

  • Redux
  • Router reagieren
  • Neu auswählen
  • Redux Think
  • Semantische Benutzeroberfläche

Randnotiz Nr. 1. Ich habe diesen wunderbaren Leitfaden kürzlich gesehen und er hat mich dazu inspiriert, einen für Rails zu schreiben.

Randnotiz Nr. 2. Hier ist das fertige Tutorial. Der Commit-Verlauf entspricht (irgendwie) den Schritten in diesem Handbuch.

Überblick

Um Ihnen einen Eindruck davon zu geben, was wir bauen werden und wie die Dinge funktionieren werden, sehen Sie sich die beiden folgenden Diagramme an.

Abbildung 1: Bearbeitung der ersten HTTP-Anfrage (dh Anfragen des Browsers an unsere Rails-App)

Das folgende Diagramm zeigt Ihre React App in Ihrem Rails-Projekt und den Pfad (durchgezogene schwarze Linie), den die erste Anforderung benötigt, um die React App an den Client (Browser) zurückzugeben.

Abbildung 2: Bearbeitung nachfolgender HTTP-Anfragen (dh Anfragen von unserer React App an unsere Rails App)

Nachdem die React App in den Browser des Benutzers geladen wurde, ist die React App für das Senden von Anforderungen an Ihre Rails App verantwortlich (durchgezogene schwarze Linie). Mit anderen Worten, sobald React geladen ist, kommen Anforderungen an Rails vom Javascript-Code und nicht vom Browser.

Weitere wichtige Hinweise, bevor wir mit dem Codieren beginnen

  • Stellen Sie sich Ihre React App als von Ihrer Rails App getrennt vor. Die React App ist ausschließlich für das Front-End bestimmt und wird im Browser des Benutzers ausgeführt. Der Rails-Teil ist ausschließlich für das Back-End bestimmt und wird auf dem Server ausgeführt. Die Rails-App weiß nichts über die React-App, außer wann ihre statischen Assets zurückgegeben werden müssen (Webpack-kompiliertes HTML, JS und CSS).
  • Sobald Ihre React App von Ihrem Browser geladen wurde, erfolgt die gesamte Logik zum Ausführen von HTTP-Anforderungen (Abrufen von Daten und Verwandeln dieser Daten in eine Ansicht) im Front-End (dh im Browser).
  • Ihre Rails-App liefert effektiv keine Ansichten außer der, die Ihrer React-App dient. In diesem Tutorial ist die einzige Rails-Ansicht/app/views/static/index.html.erb
  • Alle /api/*Pfade werden von der Rails-App verarbeitet, während alle anderen Pfade von React im Browser verarbeitet werden (nachdem Ihr Browser die erste Anforderung geladen hat). Zum Beispiel //your-app.com/somethingwird an die Rails App gesendet werden, und dann zu Ihrem Reagieren App (HTML / JS / CSS, die im Browser geladen sind bereits) zurückgeführt , das entscheidet , was auf dem Bildschirm zu zeigen.
  • Überlegungen zum Erstellen einer einseitigen App. Für dieses Tutorial nicht erforderlich, aber nützlich.
  • Reagieren Sie auf Entwurfsmuster von Komponenten. Wieder nicht notwendig, aber nützlich.

System Anforderungen

Zu Ihrer Information hier ist meine Systemkonfiguration. Das heißt nicht, dass Sie dies benötigen, aber etwas Ähnliches macht dieses Tutorial reibungsloser.

  • macOS 10.13.6 (High Sierra)
  • Ruby 2.5.1
  • Rails 5.2.1 (und Bundler 1.16.6)
  • - gem install bundler -v 1.16.6
  • Knoten 9.8.0

Zum Schluss noch zum Code!

Schritt 1: Erstellen Sie mit Webpack and React ein neues Rails-Projekt

Erstellen Sie eine neue Rails-App. Ich habe meine benannt rails-react-tutorial.

rails new rails-react-tutorial --webpack=react

Weitere Informationen zu der --webpack=reactin Rails 5.1 eingeführten Flagge finden Sie hier .

Schritt 2: Stellen Sie sicher, dass die Edelsteine ​​Webpacker und React-Rails installiert sind

Überprüfen Sie, ob sich die Edelsteine ​​Webpacker und React-Rails in Ihrem befinden Gemfile. Wenn die Edelsteine ​​nicht vorhanden sind, fügen Sie sie hinzu:

Führen Sie nun diese Befehle aus, um alles zu installieren.

bundle install
# This command might not be necessary.# If already installed, then it will# ask you to override some files.rails webpacker:install
rails webpacker:install:react rails generate react:installyarn install 

Führen Sie jetzt aus rails server -p 3000 und besuchen Sie //localhost:3000, um sicherzustellen, dass unser Projekt funktioniert.

Pro-Tipp Nr. 1 : Führen Sie ./bin/webpack-dev-serverwährend des Codierens ein separates Fenster aus, damit Änderungen den Browser automatisch erstellen und neu laden.

Pro Tipp # 2 : Wenn Sie diesen Fehler can’t activate sqlite3 (~> 1.3.6), already activated sqlite3–1.4.0 bekommen, dann ein dd gem ‘sqlite3’, ‘~>1.3.6 'zu Gemfile. Siehe diesen Link für weitere Informationen.

Schritt 3: Fügen Sie unserer Rails-App eine Controller-Klasse und Route hinzu

Fügen Sie unserer Rails-App eine neue Route hinzu. In diesem Beispiel fügen wir ` einen GET /v1/thingsEndpunkt hinzu config/routes.rb.

Diese neue Route erfordert einen ThingsController. Erstellen Sie eine neue app/controllers/v1/things_controller.rbDatei. Denken Sie daran, dass es sich im v1Ordner befinden sollte, da es zu unserer Rails-API gehört.

Unser Things-Controller gibt eine fest codierte Antwort für zurück GET /v1/things.

Zu diesem Zeitpunkt sollten Sie in der Lage sein, erneut auszuführen rails server -p 3000und zu besuchen //localhost:3000/v1/things.

Als Nächstes erstellen wir eine neue React-Komponente.

Schritt 4: Generieren Sie eine neue React-Komponente

Erstellen Sie eine HelloWorld React-Komponente, die einen String-Parameter greetingmit dem folgenden Befehl akzeptiert :

rails generate react:component HelloWorld greeting:string

Eine Datei sollte erstellt werden : app/javascript/components/HelloWorld.js.

Schritt 5: Verwenden Sie unsere HelloWorld-Komponente

Um unsere neue HelloWorld-Komponente zu verwenden und anzuzeigen, müssen Sie zwei Dinge tun: Erstellen einer Ansicht, in die diese Komponente eingebettet ist, und Hinzufügen einer Route, die auf diese Ansicht verweist.

Um eine Ansicht zu erstellen, erstellen Sie die Datei app/views/static/index.html.erbund fügen Sie Folgendes hinzu:

routes.rbFügen Sie für unsere neue Route die folgende Zeile zu unserer Datei und einen leeren StaticController hinzu, um dies zu unterstützen.

Fügen Sie dies hinzu zu app/controllers/static_controller.rb:

Sie sollten nun in der Lage sein, Ihre neue React-Komponente erneut auszuführen rails server -p 3000und zu besuchen //localhost:3000/(denken Sie daran, sie ./bin/webpack-dev-serverin einem separaten Fenster auszuführen , damit Javascript-Änderungen automatisch vom Webpack gepackt werden).

Nachdem wir nun eine React-Komponente haben, die in unserer Ansicht gerendert wird, erweitern wir unsere App, um mehrere Ansichten mit zu unterstützen react-router.

Schritt 6: React-Router hinzufügen

Führen Sie zunächst diesen Befehl zum Hinzufügen aus react-router-dom, der alle react-routerund einige zusätzliche Hilfskomponenten für das Surfen im Internet enthält und exportiert . Mehr Infos hier.

npm install --save react-router-domyarn install

Dieser Befehl sollte der package.jsonDatei die folgende Zeile hinzufügen . Hinweis: Hier wurde 4.2.2 verwendet, aber Ihre Version kann anders sein.

Verwenden wir nun React Router, um einige Routen für unser React Front-End zu erstellen.

Schritt 6: React-Router verwenden

react-routerermöglicht es uns, alle unsere UI-Routen streng mit Javascript zu verwalten. Dies bedeutet, dass wir eine einzige „App“ -Komponente benötigen, die unsere gesamte Anwendung kapselt. "App" verwendet auch React-Router, um die richtige "Seite" -Komponente für die angeforderte URL anzuzeigen.

Führen Sie diesen Befehl aus, um eine App-Komponente hinzuzufügen, die unsere gesamte Front-End-Anwendung darstellt.

rails generate react:component App

Öffnen Sie als Nächstes die Datei für die neu erstellte React-Komponente app/javascript/components/App.jsund fügen Sie Folgendes hinzu:

Wechseln Sie index.html.erbnun zu unserer neuen App-Komponente.

Zuletzt bearbeiten Sie Ihre routes.rb, damit Rails alle Anforderungen, die nicht für die API gelten, an unsere App-Komponente (über StaticController#index) sendet .

Wir können jetzt React-Router ausführen rails server -p 3000und besuchen //localhost/und //localhost/hellosehen, wie es funktioniert (denken Sie daran, dass ./bin/webpack-dev-serverdas automatische Webpacking aktiviert ist).

Als Nächstes müssen wir einige zusätzliche Abhängigkeiten installieren, bevor wir unser React-Frontend mit unserer Rails-API verbinden können.

Schritt 7: Hinzufügen von Redux, Sagas, Babel Polyfill und Axios

Fügen wir nun die folgenden Javascript-Bibliotheken für unser Frontend hinzu.

  • Redux zur Verwaltung des globalen Status unserer Anwendung.
  • Babel-Polyfill, um ausgefallene Javascript-Funktionen zu aktivieren, die in älteren Webbrowsern sonst möglicherweise nicht verfügbar sind.
  • Wählen Sie Redux erneut aus und reagieren Sie, um die Arbeit mit Redux zu vereinfachen.

Führen Sie die folgenden Schritte aus, um alles zu installieren:

npm install --save redux babel-polyfill reselect react-reduxyarn install

Jetzt werden wir diese Tools verwenden, um einen Redux State Store einzurichten, und dann einige Aktionen und Reduzierer hinzufügen, um ihn zu verwenden.

Schritt 8: Richten Sie den Redux State Store ein

In diesem Schritt richten wir den Redux State Store für unsere App mit der folgenden Vorlage ein (in den nächsten Schritten werden wir "Dinge" hinzufügen und entfernen).

{ "things": [ { "name": "...", "guid": "..." } ]}

Erstellen Sie zunächst eine configureStore.jsDatei. Dadurch wird unser Redux Store initialisiert.

Importieren und verwenden Sie nun configureStore()die App-Komponente, um einen Redux-Status zu erstellen und ihn mit unserer App zu verbinden.

Jetzt haben Sie Redux in Ihrer App installiert! Als nächstes erstellen wir eine Aktion und einen Reduzierer und beginnen mit dem Schreiben und Lesen aus unserem Redux-Status.

Schritt 9: Fügen Sie eine Aktion und einen Reduzierer hinzu

Jetzt, da die App einen Redux-Status hat, werden wir einen hinzufügenon> to HelloWorld that dispatches an Action (that we will define here) that will be received by the rootReducer().

First, add getThings() Action definition and import createStructuredSelector() and connect() into theHelloWorld Component. This maps parts of the Redux State, and Actions (i.e. dispatching getThings()) , to HelloWorld’s prop.

Next, add a on> to HelloWorld that dispatches a getThings() Action (from ./actions/index.js) on every click.

Original text


After everything is added to HelloWorld, go to //localhost:3000/hello, open the Console, and click the “getThings” button to see your Action and Reducer functions being called.

Now that you can send an Action that can be received by a Reducer, let’s have the Reducer alter the Redux State.

Step 10: Have HelloWorld read React State and display “things”

Insert a List <ul> in HelloWorld and fill it with “things” from your Redux State.

To test if this is actually working, we can initialize with some “things” data. Once this is done, we can refresh the page and see it in our list.

Now that we have a simple Action and Reducer working, we will extend this so that the Action queries our Rails API and the Reducer sets the content of “things” with the API response.

Step 11: Install Redux-Thunk

We will need Redux-Thunk to allow async workflows (like an HTTP request) to dispatch Actions.

Install redux-thunk by running this command:

npm install --save redux-thunkyarn install

Now, let’s use Thunk in our Action!

Step 12: Use redux-thunk and fetch() to query API and set React State with results

First, let’s import redux-thunk in configureStore.js and install it our Redux Store so our App can handle “Thunk” Actions.

Now test that everything is working by starting the App and loading a page.

Next, let’s change the getThings() Action to return a function that performs the following (instead of returning the Action object):

  1. Dispatch the original Action object
  2. Make a call to our Rails API.
  3. Dispatch a new Action getThingsSuccess(json) when the call succeeds.

For this step, we will also need to add the getThingsSuccess(json) Action.

Of course, this does nothing to the Redux State since our Reducer is not making any changes. To fix this, change the Reducer to handle the GET_THINGS_SUCCESS Action and return the new State (with the response from the Rails API).

Now if you start your App, navigate to localhost:3000/hello and click the button, your list should change!

There you have it. A Rails API hooked up to a React+Redux App.

(Bonus) Step 13: Installing Redux Dev Tools

Maybe I should’ve put this step earlier, but Redux Dev Tools is essential for debugging the Actions your App is sending, and how those Actions are changing your State.

This is how you install it. First, install the proper extension for your browser (Chrome, Firefox).

Next, run the following to install the library.

npm install --save-dev redux-devtools-extensionyarn install

Now, use it to initialize your Redux State Store.

After all this is done, you should be able to see a new tab, Redux, in your Chrome (or Firefox) dev tools, that lets you see which Actions were dispatched, and how each one changed the App’s State. The React tab will also show you all your components and their props and states.

Happy debugging!

(Bonus) Step 14: Semantic UI

Semantic is a great library for UI components that makes it really easy to build nice looking websites quickly.

To install this library, run the following.

npm install --save semantic-ui-css semantic-ui-reactyarn install

Add this to app/javascript/packs/application.js:

import 'semantic-ui-css/semantic.min.css';

And add this to app/views/static/index.html.erb:

 'all' %

(Bonus) Step 15: Using a Reasonable Directory Structure

This step is totally optional, and it has nothing to do with the function of the App. Just my opinion on how you should organize your files.

So as you can probably guess, stuffing your Actions into the same file as your Components, and having a single reducer for your entire App, does not scale very nicely when your App grows. Here is my suggested file structure:

app|-- javascript |-- actions |-- index.js |-- things.js |-- components |-- packs |-- reducers |-- index.js |-- things.js

(Bonus — Mar 17 2019 Update) Step 16: Install Typescript!

Typescript is just like Javascript but with types! It is described as a “strict syntactical superset of Javascript”, meaning that Javascript is considered valid Typescript, and the “type features” are all optional.

IMO Typescript is fantastic for large Javscript projects, such as a big React front-end. Below are instructions on how to install it, and a small demo of it inside our project.

First, run the following commands (taken from the Webpacker Readme):

bundle exec rails webpacker:install:typescriptyarn add @types/react @types/react-dom

Now, to see it in action, let’s rename app/javascript/reducers/things.js to things.tsx and add the following lines to the top of the file:

After you add interface Thing , let’s use it by having const initialState use that type (seen in the screenshot above), and specify that thingsReducer return an array of type Thing (also seen in the screenshot).

Everything should still work, but to see Typescript in action, lets add a default case to thingsReducer and add return 1 . Since 1 is not a Thing type we will see the output of ./bin/webpack-dev-server fail with the following:

And that’s it! You can now add Typescript .tsx files to your project and start using Types with your project.

Here’s a great overview of Typescript and why you should use it.

The End

You made it! You’ve made a Rails App that uses React and Redux. That’s pretty much it for the tutorial. I hope you had fun and learned something along the way.

If you build something with React and Rails, please do share it in the comments below — along with any questions or comments you may have for me.

Thanks for reading!