Kako stvoriti projekt Rails s React-om i Redux-ovim front-endom

Kompletan vodič za postavljanje Javascript aplikacije s jednom stranicom s Reactom i Reduxom unutar Rails projekta.

Ažuriranje (17. ožujka 2019.): Dodan je Typescript posljednjem koraku ovog projekta.

Ovaj vodič će vam pokazati kako stvoriti aplikaciju na jednoj stranici s Reactom (i Redux i Semantic UI) unutar Rails projekta.

Ovaj vodič također će sadržavati:

  • Redux
  • Reakcijski usmjerivač
  • Ponovno odaberite
  • Redux Razmislite
  • Semantičko korisničko sučelje

Napomena br. 1. Nedavno sam vidio ovaj prekrasan vodič i nadahnuo me da napišem jedan za Rails.

Napomena br. 2. Evo gotovog vodiča. Povijest urezivanja (vrsta) odgovara koracima u ovom vodiču.

Pregled

Da biste dobili osjećaj što ćemo graditi i kako će stvari funkcionirati, pogledajte 2 dijagrama u nastavku.

Dijagram 1: Obrada prvog HTTP zahtjeva (tj. Zahtjeva iz preglednika prema našoj aplikaciji Rails)

Dijagram u nastavku ilustrira vašu React aplikaciju unutar vašeg projekta Rails i put (puna crna crta) koji prvi zahtjev vodi za vraćanje React aplikacije natrag klijentu (pregledniku).

Dijagram 2: Obrada naknadnih HTTP zahtjeva (tj. Zahtjeva iz naše React aplikacije u našu Rails aplikaciju)

Nakon što se aplikacija React učita u korisnikov preglednik, aplikacija React bit će odgovorna za slanje zahtjeva u vašu aplikaciju Rails (puna crna linija). Drugim riječima, nakon što se React učita, zahtjevi za Rails dolazit će iz Javascript koda, a ne iz preglednika.

Ostale važne napomene prije nego započnemo s kodiranjem

  • Smatrajte da je vaša aplikacija React odvojena od aplikacije Rails. Aplikacija React namijenjena je samo front-endu i radi u korisničkom pregledniku. Dio Rails je strogo za pozadinu i radi na poslužitelju. Aplikacija Rails ne zna ništa o aplikaciji React, osim kada treba vratiti njenu statičku imovinu (Webpack sastavio HTML, JS i CSS).
  • Nakon što vaš preglednik učita vašu React aplikaciju, sva logika za izradu HTTP zahtjeva (dohvaćanje podataka i pretvaranje tih podataka u prikaz) vrši se na prednjem dijelu (tj. Pregledniku).
  • Vaša aplikacija Rails učinkovito ne poslužuje nijedan prikaz, osim onog koji služi vašoj aplikaciji React. U ovom vodiču jedini je Rails prikaz/app/views/static/index.html.erb
  • Sve /api/*staze obrađuje aplikacija Rails, dok sve ostale staze obrađuje React unutar preglednika (nakon što vaš preglednik učita prvi zahtjev). Primjerice, //your-app.com/somethingbit će poslani u aplikaciju Rails, a zatim vraćeni u vašu React aplikaciju (HTML / JS / CSS koji se već učitao u pregledniku), a koja će odlučiti što će se prikazati na zaslonu.
  • Razmatranja za izgradnju aplikacije na jednoj stranici. Nije potrebno za ovaj vodič, ali je korisno.
  • Uzorci dizajna komponente React. Opet, ne nužno, ali korisno.

Zahtjevi sustava

FYI, evo moje konfiguracije sustava. Ne rekavši da vam ovo treba, ali nešto slično učinit će ovaj tutorial ugodnijim.

  • macOS 10.13.6 (High Sierra)
  • Rubin 2.5.1
  • Tračnice 5.2.1 (i Bundler 1.16.6)
  • - gem install bundler -v 1.16.6
  • Čvor 9.8.0

Napokon, kôd!

Korak 1: Stvorite novi projekt Rails pomoću Webpack-a i React-a

Izradite novu aplikaciju Rails. Nazvao sam svoje rails-react-tutorial.

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

Pogledajte ovdje za više informacija o --webpack=reactzastavi uvedenoj u Rails 5.1.

Korak 2: Provjerite jesu li instalirani dragulji Webpacker i React-Rails

Provjerite jesu li dragulji Webpacker i React-Rails u vašem Gemfile. Ako dragulja nema, dodajte ga:

Sada pokrenite ove naredbe da biste sve instalirali.

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 

Sada pokrenite rails server -p 3000 i posjetite //localhost:3000kako biste bili sigurni da naš projekt djeluje.

Pro savjet # 1 : pokrenite ./bin/webpack-dev-serveru zasebnom prozoru tijekom kodiranja kako bi se sve promjene automatski gradile i ponovno učitale preglednik.

Pro savjet br. 2 : Ako dobijete ovu pogrešku can’t activate sqlite3 (~> 1.3.6), already activated sqlite3–1.4.0, zatim dd gem ‘sqlite3’, ‘~>1.3.6 'u Gemfile. Pogledajte ovu poveznicu za više informacija.

Korak 3: Dodajte klasu Controller i Route u našu aplikaciju Rails

Dodajte novu rutu u našu aplikaciju Rails. U ovom ćemo primjeru dodati GET /v1/thingskrajnju točku na config/routes.rb`.

Za ovu novu rutu bit će potreban ThingsController. Stvorite novu app/controllers/v1/things_controller.rbdatoteku. Zapamtite, trebao bi biti u v1mapi jer pripada našem Rails API-ju.

Naš će kontroler stvari vratiti kodirani odgovor za GET /v1/things.

U ovom trenutku trebali biste biti u mogućnosti ponovno pokrenuti rails server -p 3000i posjetiti //localhost:3000/v1/things.

Zatim ćemo stvoriti novu komponentu React.

Korak 4: Generirajte novu komponentu React

Stvorite komponentu HelloWorld React koja prihvaća parametar String imenovan greetingizvođenjem sljedeće naredbe:

rails generate react:component HelloWorld greeting:string

Datoteka mora biti izrađen: app/javascript/components/HelloWorld.js.

Korak 5: Upotrijebite našu komponentu HelloWorld

Da bismo koristili i vidjeli našu novu komponentu HelloWorld, potrebno je dvije stvari: stvaranje prikaza ugrađuje ovu komponentu i dodavanje rute koja usmjerava na ovaj prikaz.

Da biste stvorili prikaz, stvorite datoteku app/views/static/index.html.erbi dodajte sljedeće:

Za našu novu rutu dodajte sljedeći redak u našu routes.rbdatoteku i prazan StaticController koji će je podržati.

Dodajte ovo na app/controllers/static_controller.rb:

Sada biste trebali moći ponovno pokrenuti rails server -p 3000i posjetiti //localhost:3000/kako biste vidjeli svoju novu komponentu React (ne zaboravite pokrenuti se ./bin/webpack-dev-serveru zasebnom prozoru kako bi web-paket automatski spakirao promjene Javascripta).

Sad kad imamo komponentu React koja se prikazuje u našem pogledu, proširimo našu aplikaciju kako bismo podržavali više pogleda sa react-router.

Korak 6: Dodajte React-Router

Prvo pokrenite ovu naredbu za dodavanje react-router-domkoja uključuje i izvozi sve react-routeri neke dodatne pomoćne komponente za pregledavanje weba. Više informacija ovdje.

npm install --save react-router-domyarn install

Ova naredba treba dodati sljedeći redak u vašu package.jsondatoteku. Napomena, ovdje je korišten 4.2.2, ali vaša verzija može biti drugačija.

Sada upotrijebimo React Router da napravimo neke rute za naš React Front-End.

Korak 6: Korištenje React-Routera

react-routeromogućuje nam upravljanje svim našim rutama korisničkog sučelja strogo pomoću Javascripta. To znači da će nam trebati jedna komponenta "App" koja obuhvaća cijelu našu aplikaciju. "App" će također koristiti React-Router za predstavljanje ispravne komponente "Stranica" za URL koji se traži.

Za početak pokrenite ovu naredbu da biste dodali komponentu aplikacije koja će predstavljati cijelu našu front-end aplikaciju.

rails generate react:component App

Zatim otvorite datoteku za novostvorenu komponentu React app/javascript/components/App.jsi dodajte sljedeće ...

Sada index.html.erbprijeđite na našu novu komponentu aplikacije.

Na kraju uredite svoj routes.rbda Rails šalje sve zahtjeve koji nisu za API našoj komponenti aplikacije (putem StaticController#index).

Sada možemo trčati rails server -p 3000i posjetiti //localhost/i //localhost/hellovidjeti kako React-Router radi (sjetite se da ./bin/webpack-dev-serveromogućuje automatsko webpakiranje).

Dalje, morat ćemo instalirati neke dodatne ovisnosti prije nego što povežemo naš React front-end s našim Rails API-jem.

Korak 7: Dodavanje Redux-a, Saga, Babel Polyfill-a i Axiosa

Sad dodajmo sljedeće Javascript biblioteke za naš front-end.

  • Redux za upravljanje globalnim stanjem naše aplikacije.
  • Babel-Polyfill kako bi omogućio otmjene značajke Javascripta koje inače možda neće biti dostupne u starijim web preglednicima.
  • Ponovno odaberite i reagirajte na Redux kako biste olakšali rad s Reduxom.

Da biste sve instalirali, pokrenite sljedeće:

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

Sada ćemo ove alate koristiti za postavljanje Redux State Store-a, a zatim ćemo dodati neke radnje i reduktore da ga koristimo.

Korak 8: Postavite Redux State Store

U ovom ćemo koraku postaviti Redux State Store za našu aplikaciju sa sljedećim predloškom ("stvari" ćemo dodati i ukloniti u sljedećim koracima).

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

Prvo stvorite configureStore.jsdatoteku. Ovo će inicijalizirati našu Redux trgovinu.

Sada uvezite i koristite configureStore()u komponenti aplikacije za stvaranje Redux države i priključite je na našu aplikaciju.

Sada ste u svojoj aplikaciji instalirali Redux! Dalje, stvorit ćemo Action i Reductor i početi pisati i čitati iz naše Redux države.

Korak 9: Dodajte radnju i reduktor

Sad kad Aplikacija ima Redux State, dodati ćemo i 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!