Πώς να δημιουργήσετε ένα έργο Rails με ένα React και Redux front-end

Ένας πλήρης οδηγός για τη δημιουργία μιας εφαρμογής Javascript μιας σελίδας με το React και το Redux μέσα σε ένα έργο Rails.

Ενημέρωση (17 Μαρ 2019): Προστέθηκε πληκτρολόγιο στο τελευταίο βήμα αυτού του έργου.

Αυτό το σεμινάριο θα σας δείξει πώς να δημιουργήσετε μια εφαρμογή μιας σελίδας με το React (και το Redux and Semantic UI) μέσα σε ένα έργο Rails.

Αυτό το σεμινάριο θα περιλαμβάνει επίσης:

  • Redux
  • Αντιδράστε το δρομολογητή
  • Επιλέξτε ξανά
  • Redux Σκεφτείτε
  • Σημασιολογική διεπαφή χρήστη

Πλευρική σημείωση # 1. Είδα αυτόν τον υπέροχο οδηγό πρόσφατα και με ενέπνευσε να γράψω ένα για το Rails.

Πλευρική σημείωση # 2. Εδώ είναι το ολοκληρωμένο σεμινάριο. Το ιστορικό δεσμεύσεων αντιστοιχεί (είδος) με τα βήματα σε αυτόν τον οδηγό.

ΣΦΑΙΡΙΚΗ ΕΙΚΟΝΑ

Για να σας δώσουμε μια αίσθηση για το τι πρόκειται να χτίσουμε και πώς θα λειτουργούν τα πράγματα, δείτε τα παρακάτω 2 διαγράμματα.

Διάγραμμα 1: Διαχείριση του πρώτου αιτήματος HTTP (δηλ. Αιτήματα από το πρόγραμμα περιήγησης στην εφαρμογή Rails)

Το παρακάτω διάγραμμα απεικονίζει την εφαρμογή React σας μέσα στο έργο Rails και τη διαδρομή (συμπαγής μαύρη γραμμή) που χρειάζεται το πρώτο αίτημα για να επιστρέψετε την εφαρμογή React στον πελάτη (πρόγραμμα περιήγησης).

Διάγραμμα 2: Διαχείριση επόμενων αιτημάτων HTTP (δηλ. Αιτήματα από την εφαρμογή React στην εφαρμογή Rails)

Μετά τη φόρτωση της εφαρμογής React στο πρόγραμμα περιήγησης του χρήστη, η εφαρμογή React θα είναι υπεύθυνη για την αποστολή αιτημάτων στην εφαρμογή Rails (συμπαγής μαύρη γραμμή). Με άλλα λόγια, μόλις φορτωθεί το React, τα αιτήματα για Rails θα προέρχονται από κώδικα Javascript και όχι από το πρόγραμμα περιήγησης.

Άλλες σημαντικές σημειώσεις πριν ξεκινήσουμε την κωδικοποίηση

  • Σκεφτείτε την εφαρμογή React ως ξεχωριστή από την εφαρμογή Rails. Η εφαρμογή React είναι αυστηρά για το front-end και εκτελείται στο πρόγραμμα περιήγησης του χρήστη. Το τμήμα Rails προορίζεται αποκλειστικά για το back-end και λειτουργεί στον διακομιστή. Η εφαρμογή Rails δεν γνωρίζει τίποτα σχετικά με την εφαρμογή React, εκτός από το πότε πρέπει να επιστρέψει τα στατικά στοιχεία της (Webpack, HTML, JS και CSS).
  • Μόλις η εφαρμογή React φορτωθεί από το πρόγραμμα περιήγησής σας, όλη η λογική για την υποβολή αιτημάτων HTTP (ανάκτηση δεδομένων και μετατροπή αυτών των δεδομένων σε προβολή) γίνεται στο μπροστινό μέρος (π.χ. πρόγραμμα περιήγησης).
  • Η εφαρμογή Rails δεν εξυπηρετεί αποτελεσματικά προβολές εκτός από αυτήν που εξυπηρετεί την εφαρμογή React. Σε αυτό το σεμινάριο, η μόνη προβολή Rails είναι/app/views/static/index.html.erb
  • Ο /api/*χειρισμός όλων των διαδρομών γίνεται από την εφαρμογή Rails, ενώ όλες οι άλλες διαδρομές αντιμετωπίζονται από το React μέσα στο πρόγραμμα περιήγησης (αφού το πρόγραμμα περιήγησής σας φορτώσει το πρώτο αίτημα). Για παράδειγμα, //your-app.com/somethingθα σταλεί στην εφαρμογή Rails και, στη συνέχεια, θα επιστρέψει στην εφαρμογή React (το HTML / JS / CSS που έχει ήδη φορτωθεί στο πρόγραμμα περιήγησης), η οποία θα αποφασίσει τι θα εμφανιστεί στην οθόνη.
  • Σκέψεις για τη δημιουργία μιας εφαρμογής μιας σελίδας. Δεν είναι απαραίτητο για αυτό το σεμινάριο αλλά χρήσιμο.
  • Αντιδράστε μοτίβα σχεδίασης εξαρτημάτων. Και πάλι, δεν είναι απαραίτητο αλλά χρήσιμο.

Απαιτήσεις συστήματος

FYI εδώ είναι η διαμόρφωση του συστήματός μου. Όχι λέγοντας ότι το χρειάζεστε, αλλά κάτι παρόμοιο θα κάνει αυτή την εμπειρία εκμάθησης πιο ομαλή.

  • macOS 10.13.6 (High Sierra)
  • Ρουμπίνι 2.5.1
  • Ράγες 5.2.1 (και Bundler 1.16.6)
  • - gem install bundler -v 1.16.6
  • Κόμβος 9.8.0

Τέλος, στον κώδικα!

Βήμα 1: Δημιουργήστε ένα νέο έργο Rails με το Webpack και το React

Δημιουργήστε μια νέα εφαρμογή Rails. Έχω ονομάσει δικό μου rails-react-tutorial.

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

Δείτε εδώ για περισσότερες πληροφορίες σχετικά με τη --webpack=reactσημαία που παρουσιάζεται στο Rails 5.1.

Βήμα 2: Βεβαιωθείτε ότι έχουν εγκατασταθεί οι πολύτιμοι λίθοι Webpacker και React-Rails

Ελέγξτε αν οι πολύτιμοι λίθοι του Webpacker και του React-Rails βρίσκονται στο δικό σας Gemfile. Εάν οι πολύτιμοι λίθοι δεν είναι εκεί, προσθέστε το:

Τώρα εκτελέστε αυτές τις εντολές για να εγκαταστήσετε τα πάντα.

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 

Τώρα εκτελέστε rails server -p 3000 και επισκεφθείτε //localhost:3000για να βεβαιωθείτε ότι το έργο μας λειτουργεί.

Επαγγελματική συμβουλή # 1 : εκτελέστε ./bin/webpack-dev-serverσε ξεχωριστό παράθυρο ενώ κωδικοποιείτε για να δημιουργήσετε αυτόματα αλλαγές και να φορτώσετε ξανά το πρόγραμμα περιήγησης.

Επαγγελματική συμβουλή # 2 : Εάν λάβετε αυτό το σφάλμα can’t activate sqlite3 (~> 1.3.6), already activated sqlite3–1.4.0 τότε dd gem ‘sqlite3’, ‘~>1,3,6 'στο Gemfile. Δείτε αυτόν τον σύνδεσμο για περισσότερες πληροφορίες.

Βήμα 3: Προσθέστε μια κλάση ελεγκτή και Route, στην εφαρμογή Rails

Προσθέστε μια νέα διαδρομή στην εφαρμογή Rails. Για αυτό το παράδειγμα, θα προσθέσουμε το GET /v1/thingsτελικό σημείο στο config/routes.rb".

Αυτή η νέα διαδρομή απαιτεί ένα ThingsController. Δημιουργήστε ένα νέο app/controllers/v1/things_controller.rbαρχείο. Θυμηθείτε, πρέπει να βρίσκεται στο v1φάκελο επειδή ανήκει στο Rails API.

Ο ελεγκτής των πραγμάτων μας θα επιστρέψει μια κωδικοποιημένη απόκριση για GET /v1/things.

Σε αυτό το σημείο, θα πρέπει να μπορείτε να εκτελέσετε ξανά rails server -p 3000και να επισκεφθείτε //localhost:3000/v1/things.

Στη συνέχεια, θα δημιουργήσουμε ένα νέο στοιχείο React.

Βήμα 4: Δημιουργήστε ένα νέο στοιχείο React

Δημιουργήστε ένα στοιχείο HelloWorld React που δέχεται μια παράμετρο String που ονομάζεται greetingεκτελώντας την ακόλουθη εντολή:

rails generate react:component HelloWorld greeting:string

Θα πρέπει να δημιουργηθεί ένα αρχείο: app/javascript/components/HelloWorld.js.

Βήμα 5: Χρησιμοποιήστε το στοιχείο HelloWorld

Για να χρησιμοποιήσουμε και να δούμε το νέο μας στοιχείο HelloWorld, πρέπει να κάνουμε 2 πράγματα: να δημιουργήσουμε μια προβολή που ενσωματώνει αυτό το στοιχείο και να προσθέσουμε μια διαδρομή για να δείξουμε αυτήν την προβολή.

Για να δημιουργήσετε μια προβολή, δημιουργήστε το αρχείο app/views/static/index.html.erbκαι προσθέστε τα εξής:

Για τη νέα μας διαδρομή, προσθέστε την ακόλουθη γραμμή στο routes.rbαρχείο μας και έναν κενό StaticController για να το υποστηρίξετε.

Προσθέστε το σε app/controllers/static_controller.rb:

Τώρα θα πρέπει να μπορείτε να εκτελέσετε ξανά rails server -p 3000και να επισκεφθείτε //localhost:3000/για να δείτε το νέο σας στοιχείο React (θυμηθείτε να εκτελέσετε ./bin/webpack-dev-serverσε ξεχωριστό παράθυρο για να έχετε αυτόματα αλλαγές στο Javascript από το πακέτο web).

Τώρα που έχουμε ένα στοιχείο React που αποδίδεται στην άποψή μας, ας επεκτείνουμε την εφαρμογή μας για να υποστηρίξουμε πολλές προβολές react-router.

Βήμα 6: Προσθήκη React-Router

Αρχικά, εκτελέστε αυτήν την εντολή για προσθήκη react-router-dom, η οποία περιλαμβάνει και εξάγει όλα react-routerκαι ορισμένα πρόσθετα βοηθητικά στοιχεία για την περιήγηση στον ιστό. Περισσότερες πληροφορίες εδώ.

npm install --save react-router-domyarn install

Αυτή η εντολή θα πρέπει να προσθέσει την ακόλουθη γραμμή στο package.jsonαρχείο σας . Σημείωση, το 4.2.2 χρησιμοποιήθηκε εδώ, αλλά η έκδοσή σας θα μπορούσε να είναι διαφορετική.

Τώρα ας χρησιμοποιήσουμε το React Router για να κάνουμε κάποιες διαδρομές για το React Front-End.

Βήμα 6: Χρήση του React-Router

react-routerμας επιτρέπει να διαχειριζόμαστε όλες τις διαδρομές διεπαφής χρήστη αυστηρά με Javascript. Αυτό σημαίνει ότι θα χρειαστούμε ένα μόνο στοιχείο "Εφαρμογή" που θα ενσωματώνει ολόκληρη την εφαρμογή μας. Το "App" θα χρησιμοποιήσει επίσης το React-Router για να παρουσιάσει το σωστό στοιχείο "Page" για το URL που ζητείται.

Για να ξεκινήσετε, εκτελέστε αυτήν την εντολή για να προσθέσετε ένα στοιχείο εφαρμογής που θα αντιπροσωπεύει ολόκληρη την εφαρμογή front-end.

rails generate react:component App

Στη συνέχεια, ανοίξτε το αρχείο για το νέο συστατικό React app/javascript/components/App.jsκαι προσθέστε τα ακόλουθα…

Τώρα αλλάξτε index.html.erbγια να δείξετε το νέο μας στοιχείο εφαρμογής.

Τέλος, επεξεργαστείτε το routes.rbγια να κάνετε Rails να στέλνουν όλα τα αιτήματα που δεν αφορούν το API στο στοιχείο της εφαρμογής μας (μέσω StaticController#index).

Τώρα μπορούμε να τρέξουμε rails server -p 3000και να επισκεφθούμε //localhost/και //localhost/helloνα δούμε το React-Router να λειτουργεί (θυμηθείτε ότι ./bin/webpack-dev-serverεπιτρέπει την αυτόματη διαδικτυακή συσκευασία).

Στη συνέχεια, θα πρέπει να εγκαταστήσουμε μερικές επιπλέον εξαρτήσεις για να μπορέσουμε να συνδέσουμε το React front-end με το Rails API.

Βήμα 7: Προσθήκη Redux, Sagas, Babel Polyfill και Axios

Τώρα ας προσθέσουμε τις ακόλουθες βιβλιοθήκες Javascript για το front-end μας.

  • Redux για τη διαχείριση της παγκόσμιας κατάστασης της εφαρμογής μας.
  • Το Babel-Polyfill επιτρέπει ενεργοποιημένες λειτουργίες Javascript που διαφορετικά δεν θα ήταν διαθέσιμες σε παλαιότερα προγράμματα περιήγησης ιστού.
  • Επιλέξτε ξανά και React-Redux για να διευκολύνετε την εργασία με το Redux.

Για να εγκαταστήσετε τα πάντα, εκτελέστε τα εξής:

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

Τώρα θα χρησιμοποιήσουμε αυτά τα εργαλεία για να δημιουργήσουμε ένα Redux State Store και, στη συνέχεια, προσθέσουμε ορισμένες ενέργειες και μειωτές για να το χρησιμοποιήσουμε.

Βήμα 8: Ρυθμίστε το Redux State Store

Σε αυτό το βήμα, θα ρυθμίσουμε το Redux State Store για την εφαρμογή μας με το ακόλουθο πρότυπο (θα προσθέσουμε και θα αφαιρέσουμε τα "πράγματα" στα επόμενα βήματα).

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

Αρχικά, δημιουργήστε ένα configureStore.jsαρχείο. Αυτό θα προετοιμάσει το Redux Store μας.

Τώρα εισαγάγετε και χρησιμοποιήστε configureStore()στο App Component για να δημιουργήσετε μια κατάσταση Redux και να την συνδέσετε στην εφαρμογή μας.

Τώρα έχετε εγκαταστήσει το Redux στην εφαρμογή σας! Στη συνέχεια, θα δημιουργήσουμε μια Ενέργεια και έναν Μειωτή, και θα αρχίσουμε να γράφουμε και να διαβάζουμε από το Redux State.

Βήμα 9: Προσθέστε μια ενέργεια και έναν μειωτή

Τώρα που η εφαρμογή έχει μια κατάσταση Redux, θα προσθέσουμε ένα on> to HelloWorld that dispatches an Action (that we will define here) that will be received b y 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 dispatc hes a getThings() Action (from ./actions/index.js) on every click.

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!