Kaip sukurti „Rails“ projektą su „React“ ir „Redux“ sąsaja

Išsamus vadovas, kaip sukurti vieno puslapio „Javascript“ programą su „React“ ir „Redux“ projekto „Rails“ viduje.

Atnaujinimas (2019 m. Kovo 17 d.): Paskutiniame šio projekto žingsnyje pridėtas mašinraštis.

Ši pamoka parodys, kaip „Rails“ projekte sukurti vieno puslapio programą su „React“ (ir „Redux“ bei „Semantic UI“).

Šioje pamokoje taip pat bus:

  • Redux
  • „React Router“
  • Pasirinkite iš naujo
  • Redux Pagalvok
  • Semantinė vartotojo sąsaja

Šoninė pastaba Nr. 1. Neseniai mačiau šį nuostabų vadovą ir jis mane įkvėpė parašyti vieną „Rails“.

2 šalutinis užrašas. Čia yra baigta pamoka. Įsipareigojimų istorija (rūšis) atitinka šio vadovo veiksmus.

Apžvalga

Norėdami suprasti, ką mes kursime ir kaip viskas veiks, žr. 2 toliau pateiktas diagramas.

1 diagrama: pirmosios HTTP užklausos (pvz., Naršyklės užklausų mūsų „Rails“ programai) tvarkymas

Žemiau pateikta schema iliustruoja jūsų „React“ programą „Rails“ projekte ir kelią (ištisą juodą liniją), kurį eina pirmoji užklausa, kad „ React“ programa būtų grąžinta klientui (naršyklei).

2 diagrama: Vėlesnių HTTP užklausų (ty užklausų iš „React App“ į „Rails“ programą) tvarkymas

Įkėlus „React“ programą į vartotojo naršyklę, „React“ programa bus atsakinga už užklausų siuntimą jūsų „Rails“ programai (ištisinė juoda linija). Kitaip tariant, įkėlus „React“, „Rails“ užklausos bus teikiamos iš „Javascript“ kodo, o ne iš naršyklės.

Kitos svarbios pastabos prieš pradedant koduoti

  • Pagalvokite, kad „React“ programa yra atskira nuo „Rails“ programos. „React“ programa yra skirta tik vartotojo sąsajai ir veikia vartotojo naršyklėje. „Rails“ dalis yra skirta tik programinei įrangai ir veikia serveryje. „Rails“ programa nieko nežino apie „React“ programą, išskyrus tai, kada grąžinti statinį turtą („Webpack“ sudarytas HTML, JS ir CSS).
  • Kai naršyklė įkels jūsų „React“ programą, visa logika, reikalinga HTTP užklausoms pateikti (duomenims nuskaityti ir tuos duomenis paversti rodiniu), atliekama priekinėje dalyje (ty naršyklėje).
  • Jūsų „Rails“ programa faktiškai neteikia jokių peržiūrų, išskyrus tą, kuri aptarnauja jūsų „React“ programą. Šioje pamokoje vienintelis „Rails“ rodinys yra/app/views/static/index.html.erb
  • Visus /api/*kelius tvarko „Rails“ programa, o visus kitus kelius - „React“ naršyklėje (kai jūsų naršyklė įkėlė pirmąją užklausą). Pvz., //your-app.com/somethingBus nusiųstas į „Rails“ programą, o tada grįš atgal į jūsų „React“ programą (HTML / JS / CSS, kuri jau buvo įkelta į naršyklę), kuri nuspręs, ką rodyti ekrane.
  • Vieno puslapio programos kūrimo svarstymai. Šiai pamokai nereikia, bet naudinga.
  • „React Component“ dizaino modeliai. Vėlgi, nebūtina, bet naudinga.

Sistemos reikalavimai

FYI čia yra mano sistemos konfigūracija. Negalima sakyti, kad jums to reikia, bet kažkas panašaus padarys šią mokymo programą sklandesnę.

  • „macOS 10.13.6“ („High Sierra“)
  • Rubinas 2.5.1
  • Bėgiai 5.2.1 (ir „Bundler 1.16.6“)
  • - brangakmenių diegimo paketas -v 1.16.6
  • Mazgas 9.8.0

Galiausiai, prie kodo!

1 žingsnis: sukurkite naują „Rails“ projektą naudodami „Webpack and React“

Sukurkite naują „Rails“ programą. Aš pavadinau savo rails-react-tutorial.

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

Čia rasite daugiau informacijos apie „ --webpack=reactRails 5.1“ pristatytą vėliavą.

2 žingsnis: įsitikinkite, kad įdiegti „Webpacker“ ir „React-Rails“ brangakmeniai

Patikrinkite, ar „ Webpacker“ ir „ React-Rails“ brangakmeniai yra jūsų Gemfile. Jei brangakmenių nėra, pridėkite jį:

Dabar paleiskite šias komandas, kad viską įdiegtumėte.

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 

Dabar paleiskite rails server -p 3000 ir apsilankykite, //localhost:3000kad įsitikintumėte, jog mūsų projektas veikia.

„Pro“ patarimas Nr. 1 : paleiskite ./bin/webpack-dev-serverkoduodami atskirame lange, kad pakeitimai automatiškai sukurtų ir iš naujo įkeltų naršyklę.

„Pro“ patarimas Nr. 2 : Jei gaunate šią klaidą can’t activate sqlite3 (~> 1.3.6), already activated sqlite3–1.4.0, tada dd gem ‘sqlite3’, ‘~>„Gemfile“ - 1.3.6 '. Norėdami sužinoti daugiau informacijos, žiūrėkite šią nuorodą.

3 žingsnis: pridėkite „Controller“ klasę ir „Route“ prie „Rails“ programos

Pridėkite naują maršrutą prie „Rails“ programos. Šiame pavyzdyje pridėsime GET /v1/thingsgalinį tašką į config/routes.rb.

Šiam naujam maršrutui reikės „ThingsController“. Sukurkite naują app/controllers/v1/things_controller.rbfailą. Atminkite, kad jis turėtų būti v1aplanke, nes jis priklauso mūsų „Rails“ API.

Mūsų daiktų valdiklis pateiks griežtai užkoduotą atsakymą GET /v1/things.

Šiuo metu turėtumėte galėti iš naujo bėgti rails server -p 3000ir apsilankyti //localhost:3000/v1/things.

Tada sukursime naują „React“ komponentą.

4 žingsnis: sugeneruokite naują „React“ komponentą

Sukurkite „HelloWorld React“ komponentą, kuris priima eilutės parametrą, pavadintą greetingvykdant šią komandą:

rails generate react:component HelloWorld greeting:string

Failas turi būti sukurtas: app/javascript/components/HelloWorld.js.

5 žingsnis: naudokite mūsų „HelloWorld“ komponentą

Norint naudoti ir pamatyti naująjį „HelloWorld“ komponentą, mums reikia 2 dalykų: sukūrę rodinį, įterpiate šį komponentą, ir pridėkite kelią į rodinį.

Norėdami sukurti rodinį, sukurkite failą app/views/static/index.html.erbir pridėkite:

Naujam maršrutui į routes.rbfailą pridėkite šią eilutę ir tuščią „StaticController“, kad ją palaikytumėte.

Pridėti tai prie app/controllers/static_controller.rb:

Dabar turėtumėte galėti paleisti iš naujo rails server -p 3000ir apsilankyti, //localhost:3000/kad pamatytumėte savo naują „React“ komponentą (nepamirškite paleisti ./bin/webpack-dev-serveratskirame lange, kad „Javascript“ pakeitimai būtų automatiškai supakuoti į internetinę paketą).

Dabar, kai turime „React“ komponentą, kuris pateikiamas mūsų požiūriu, išplėsime programą, kad būtų palaikomi keli rodiniai react-router.

6 veiksmas: pridėkite „React-Router“

Pirmiausia vykdykite šią komandą, kad pridėtumėte react-router-dom, kuri apima ir eksportuoja visus react-routerir keletą papildomų pagalbinių komponentų, skirtų naršyti internete. Daugiau informacijos čia.

npm install --save react-router-domyarn install

Ši komanda turėtų pridėti šią eilutę prie package.jsonfailo. Atkreipkite dėmesį, kad čia buvo naudojama 4.2.2 versija, tačiau jūsų versija gali būti kitokia.

Dabar naudokime „React Router“, kad atliktume kelis „React Front-End“ maršrutus.

6 žingsnis: „React-Router“ naudojimas

react-routerleidžia mums griežtai valdyti visus savo vartotojo sąsajos maršrutus naudojant „Javascript“. Tai reiškia, kad mums reikės vieno „Programos“ komponento, apimančio visą mūsų programą. „App“ taip pat naudos „React-Router“, kad pateiktų teisingą „Page“ komponentą prašomam URL.

Norėdami pradėti, paleiskite šią komandą, kad pridėtumėte programos komponentą, kuris atspindės visą mūsų priekinės programos programą.

rails generate react:component App

Tada atidarykite naujai sukurto „React“ komponento failą app/javascript/components/App.jsir pridėkite šiuos…

Dabar pakeiskite index.html.erb, kad nurodytumėte mūsų naują programos komponentą.

Galiausiai redaguokite routes.rb, kad „Rails“ išsiųstų visas užklausas, kurios nėra skirtos API, į mūsų programos komponentą (per StaticController#index).

Mes dabar gali paleisti rails server -p 3000ir apsilankymas //localhost/ir //localhost/hellopamatyti Pareikšk-Router darbo (nepamirškite ./bin/webpack-dev-serverleidžia automatinį webpacking).

Tada mes turėsime įdiegti keletą papildomų priklausomybių, kad galėtume prijungti „React“ sąsają su „Rails“ API.

7 veiksmas: pridėkite „Redux“, „Sagas“, „Babel Polyfill“ ir „Axios“

Dabar pridėkime šias „Javascript“ bibliotekas mūsų sąsajoje.

  • Redux valdyti mūsų programos visuotinę būklę.
  • „Babel-Polyfill“, kad įgalintumėte įmantrias „Javascript“ funkcijas, kurių kitu atveju galbūt nėra senesnėse žiniatinklio naršyklėse.
  • Norėdami iš naujo pasirinkti „Redux“, pasirinkite „React-Redux“.

Norėdami viską įdiegti, vykdykite šiuos veiksmus:

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

Dabar mes naudosime šiuos įrankius, norėdami sukurti „Redux“ valstybinę parduotuvę, tada pridėkite keletą veiksmų ir reduktorių, kad galėtumėte ją naudoti.

8 žingsnis: Nustatykite „Redux State Store“

Šiame žingsnyje mes sukursime „Redux State Store“ savo programai su tokiu šablonu (mes pridėsime ir pašalinsime „dalykus“ atlikdami kitus veiksmus).

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

Pirmiausia sukurkite configureStore.jsfailą. Tai inicijuos mūsų „Redux Store“.

Dabar importuokite ir naudokite configureStore()„App Component“, kad sukurtumėte „Redux“ būseną ir prijunkite ją prie mūsų programos.

Dabar jūsų programoje įdiegta „Redux“! Tada sukursime veiksmą ir reduktorių ir pradėsime rašyti ir skaityti iš savo Redux būsenos.

9 veiksmas: pridėkite veiksmą ir reduktorių

Dabar, kai programoje yra „Redux“ būsena, pridėsime 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!