Sådan oprettes et Rails-projekt med en React og Redux front-end
En komplet guide til opsætning af en enkelt-side Javascript-app med React og Redux i et Rails-projekt.

Opdatering (17. mar. 2019): Tilføjet typeskript til det sidste trin i dette projekt.
Denne vejledning viser dig, hvordan du opretter en enkelt-sidet app med React (og Redux og Semantic UI) i et Rails-projekt.
Denne vejledning inkluderer også:
- Redux
- Reager router
- Vælg igen
- Redux tænker
- Semantisk brugergrænseflade
Side note nr. 1. Jeg så denne vidunderlige guide for nylig, og det inspirerede mig til at skrive en til Rails.
Side note # 2. Her er den færdige vejledning. Forpligtelseshistorikken svarer (slags) til trinene i denne vejledning.
Oversigt
For at give dig en fornemmelse af, hvad vi skal bygge, og hvordan tingene fungerer, se de 2 diagrammer nedenfor.
Diagram 1: Håndtering af den første HTTP-anmodning (dvs. anmodninger fra browseren til vores Rails-app)
Diagrammet nedenfor illustrerer din React-app inde i dit Rails-projekt og den sti (sort linje), som den første anmodning tager for at returnere React-appen tilbage til klienten (browser).

Diagram 2: Håndtering af efterfølgende HTTP-anmodninger (dvs. anmodninger fra vores React-app til vores Rails-app)
Når React App er indlæst i brugerens browser, er React App ansvarlig for at sende anmodninger til din Rails App (sort sort linje). Med andre ord, når React er indlæst, kommer anmodninger til Rails fra Javascript-kode og ikke fra browseren.

Andre vigtige bemærkninger, inden vi begynder at kode
- Tænk på, at din React-app er adskilt fra din Rails-app. React-appen er strengt taget til front-end og kører i brugerens browser. Rails-delen er strengt taget til back-end og kører på serveren. Rails-appen ved ikke noget om React-appen undtagen hvornår de statiske aktiver skal returneres (Webpack kompileret HTML, JS og CSS).
- Når din React-app er indlæst af din browser, udføres al logik til at foretage HTTP-anmodninger (hente data og gøre disse data til en visning) i frontend (dvs. browser).
- Din Rails-app serverer effektivt ikke nogen visninger undtagen den, der betjener din React-app. I denne vejledning er den eneste Rails-visning
/app/views/static/index.html.erb
- Alle
/api/*
stier håndteres af Rails App, mens alle andre stier håndteres af React inde i browseren (efter at din browser har indlæst den første anmodning). For eksempel//your-app.com/something
sendes til Rails-appen og returneres derefter til din React-app (HTML / JS / CSS, der allerede er indlæst i browseren), som bestemmer, hvad der skal vises på skærmen. - Overvejelser ved opbygning af en enkelt-side app. Ikke nødvendigt til denne vejledning, men nyttigt.
- Reager komponentdesignmønstre. Igen, ikke nødvendigt, men nyttigt.
Systemkrav
Her er min systemkonfiguration. Ikke at sige, at du har brug for dette, men noget lignende vil gøre denne tutorial-oplevelse glattere.
- macOS 10.13.6 (High Sierra)
- Rubin 2.5.1
- Skinner 5.2.1 (og bundler 1.16.6)
- - gem installere bundler -v 1.16.6
- Knude 9.8.0
Endelig videre til koden!
Trin 1: Opret et nyt Rails-projekt med Webpack og React
Opret en ny Rails-app. Jeg har navngivet min rails-react-tutorial
.
rails new rails-react-tutorial --webpack=react
Se her for mere info om --webpack=react
flag introduceret i Rails 5.1.
Trin 2: Sørg for, at Webpacker- og React-Rails-ædelstene er installeret
Kontroller, om Webpacker og React-Rails ædelstene er i din Gemfile
. Hvis ædelstene ikke er der, skal du tilføje det:

Kør nu disse kommandoer for at installere alt.
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
Kør nu rails server -p 3000
og besøg //localhost:3000
for at sikre, at vores projekt fungerer.
Pro Tip nr. 1 : Kør ./bin/webpack-dev-server
i et separat vindue, mens du koder for at få eventuelle ændringer automatisk til at oprette og genindlæse browseren.
Pro Tip nr. 2 : Hvis du får denne fejl can’t activate sqlite3 (~> 1.3.6), already activated sqlite3–1.
4.0 så en dd gem ‘sqlite3’, ‘~>
1.3.6 'til Gemfile. Se dette link for mere info.
Trin 3: Føj en controller-klasse og rute til vores Rails-app
Tilføj en ny rute til vores Rails-app. I dette eksempel vil vi føje GET /v1/things
slutpunkt til config/routes.rb
`.

Denne nye rute kræver en ThingsController. Opret en ny app/controllers/v1/things_controller.rb
fil. Husk, det skal være i v1
mappen, fordi det hører til vores Rails API.

Vores ting-controller vil returnere et hårdt kodet svar for GET /v1/things
.
På dette tidspunkt skal du være i stand til at køre igen rails server -p 3000
og besøge //localhost:3000/v1/things
.

Dernæst opretter vi en ny React-komponent.
Trin 4: Generer en ny React-komponent
Opret en HelloWorld React-komponent, der accepterer en strengparameter navngivet greeting
ved at køre følgende kommando:
rails generate react:component HelloWorld greeting:string
Der bør skabes en fil: app/javascript/components/HelloWorld.js
.

Trin 5: Brug vores HelloWorld-komponent
For at bruge og se vores nye HelloWorld-komponent er vi nødt til to ting: Opret en visning indlejrer denne komponent og tilføj en rute til at pege på denne visning.
For at oprette en visning skal du oprette filen app/views/static/index.html.erb
og tilføje følgende:

For vores nye rute skal du tilføje følgende linje til vores routes.rb
fil og en tom StaticController for at understøtte den.

Føj dette til app/controllers/static_controller.rb
:

Du skal nu være i stand til at genkøre rails server -p 3000
og besøge for //localhost:3000/
at se din nye React-komponent (husk at køre ./bin/webpack-dev-server
i et separat vindue for at få Javascript-ændringer automatisk pakket med webpack).

Nu hvor vi har en React-komponent, der gengives efter vores opfattelse, lad os udvide vores app til at understøtte flere visninger med react-router
.
Trin 6: Tilføj React-Router
Kør først denne kommando for at tilføje react-router-dom
, som inkluderer og eksporterer alle react-router
og nogle ekstra hjælpekomponenter til browsing. Mere info her.
npm install --save react-router-domyarn install
Denne kommando skal føje følgende linje til din package.json
fil. Bemærk, 4.2.2 blev brugt her, men din version kunne være anderledes.

Lad os nu bruge React Router til at lave nogle ruter til vores React Front-End.
Trin 6: Brug af React-Router
react-router
giver os mulighed for at administrere alle vores UI-ruter nøjagtigt med Javascript. Dette betyder, at vi har brug for en enkelt "App" -komponent, der indkapsler hele vores applikation. "App" bruger også React-Router til at præsentere den korrekte "Side" -komponent for den anmodede URL.
For at starte skal du køre denne kommando for at tilføje en App-komponent, der repræsenterer hele vores front-end-applikation.
rails generate react:component App
Åbn derefter filen for den nyoprettede React-komponent app/javascript/components/App.js
, og tilføj følgende ...

Skift nu for index.html.erb
at pege på vores nye App-komponent.

Endelig rediger din for routes.rb
at få Rails til at sende alle anmodninger, der ikke er til API'en, til vores App-komponent (via StaticController#index
).

Vi kan nu løbe rails server -p 3000
og besøge //localhost/
og //localhost/hello
se React-Router arbejde (husk ./bin/webpack-dev-server
aktiverer auto-webpacking).
Dernæst bliver vi nødt til at installere nogle yderligere afhængigheder, før vi kan forbinde vores React-frontend til vores Rails API.
Trin 7: Tilføjelse af Redux, Sagas, Babel Polyfill og Axios
Lad os nu tilføje følgende Javascript-biblioteker til vores front-end.
- Redux til at styre den globale tilstand af vores ansøgning.
- Babel-Polyfill for at aktivere fancy Javascript-funktioner, som ellers muligvis ikke er tilgængelige i ældre webbrowsere.
- Vælg igen og React-Redux for at gøre det lettere at arbejde med Redux.
For at installere alt skal du køre følgende:
npm install --save redux babel-polyfill reselect react-reduxyarn install
Nu bruger vi disse værktøjer til at oprette en Redux State Store og derefter tilføje nogle handlinger og reduktioner for at bruge den.
Trin 8: Opret Redux State Store
I dette trin opretter vi Redux State Store til vores app med følgende skabelon (vi tilføjer og fjerner "ting" i de næste trin).
{ "things": [ { "name": "...", "guid": "..." } ]}
Opret først en configureStore.js
fil. Dette initialiserer vores Redux Store.

Importer og brug nu configureStore()
i appkomponenten til at oprette en Redux-tilstand og tilslutte den til vores app.

Nu har du Redux installeret i din app! Dernæst opretter vi en handling og en reduktion og begynder at skrive og læse fra vores Redux-stat.
Trin 9: Tilføj en handling og en reduktion
Nu hvor appen har en Redux-tilstand, tilføjer vi en
y the rootRed
ucer().
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
hes a getTh
ings() 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):
- Dispatch the original Action object
- Make a call to our Rails API.
- 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!