I've just wrapped up my latest project: a content tracking application that used React, Redux, and a Rails API to persist the user-inputted data. The objective of this project was to create a single-page application using these technologies. Here is a link to the frontend repository as well as the backend repository. To try out the application yourself, simply clone both repositories to your machine, run
bundle install, start the rails server with
rails s, and run
npm install && start on the frontend.
I decided to go with a content/entertainment tracking app because it was similar to previous projects and would allow me to focus on how the technologies differed/improved. I started by brainstorming how I wanted to set up my backend (mainly what the models would look like). While outlining my backend, I was also thinking about the components that I was going to have in my React app. I came up with a rough list, as well as a sketch on how I wanted them to look on the page. Since I was using Redux to manage the state of my application, I also thought about which components I was going to have to connect to the store and how.
To create the rails backend, I created a new rails project using the
--api flag. I used the resource generator to create the skeleton of what I needed to handle content and reviews in rails. To protect the data on the server side, I added validations to both my Content and Review models. For example, used a method to persist content titles and types in title case. For reviews, I used a validation to make sure that the rating was between 1 and 5. In thinking about the future fetch request I was going to send to my backend to retrieve my seed data, I used the Active Model Serializers gem to send my object associations in JSON. I later removed the associations but I'll talk about this later.
After wrapping up my backend, I created my frontend application using
create-react-app. First, I installed the majority of the libraries I needed for this project: Redux, React-Router, and Redux-Thunk. Then, I focused on building my actions, reducer, and dispatch since this part was the trickiest for me. Initially I attempted to normalize my database structure in my Redux store however I found that my new state objects weren't being created properly. I then decided to separate my reducer and actions and use the
combineReducers method from Redux. I used hooks where I could because I found they made the process easier; I even added the
react-hook-form library to render both forms in my application. I had separate components for my About page, the Nav Bar, Content List, Content, Review List, Review, and a component for each of the forms. This was a single-page application but I still tried to stick to RESTful routing where it made sense. I used
react-router to mimic this convention on the client side. For example, clicking on the New Review link under one of the content would take you to "/contents/1/review/new". I usually waited to test my app's functionality after I completed all of the pieces that were needed to complete a particular action.
While programming this application, I ran into a few roadblocks that left me stumped. I used a combination of my notes, official documentation, and Google to resolve the problems I ran into. For example, after having a hard time organizing my store, I used the
combineReducers function from Redux. After I fetched my data, I was having a hard time adding it to the store until I realized that I was misusing the spread operator. Having the backend open whenever I made calls to my rails API was incredibly informative when I was testing my GET, POST, and DELETE calls. Moving forward, I hope to clean up the presentation of the app. I'd like to try using a UI library that could help it look more presentable than the minimal CSS I've added.