Vacay Away: React with Redux Project

Kotomi Noguchi
4 min readApr 12, 2021
Home page of my web application

Final React project for Flatiron’s Software Engineering bootcamp completed! There was a lot of content to learn this phase, being introduced to React JS, state, props, hooks, Redux, Thunk… I also learned styling with Material UI on my own, which turned out to be super fun!

I decided to build a vacation planner application just in time for summer with a React JS frontend and a Rails API backend. Before you write it off as cliche, I made my project dynamic and visual, where the user is able to assign vacation days to their activities which moves the activity between the day planners.

Here are my frontend and backend GitHub repositories.

Project Requirements

  1. Be written in ES6 as much as possible

2. Have one HTML page to render your react-redux application

3. Have 5 stateless component and 3 routes

4. Make use of react-router and proper RESTful routing

5. Use Redux middleware to respond to and modify state change

6. Make use of async actions and redux-thunk middleware to send data to and receive data from a server

7. Rails API should handle the data persistence with a database. You should be using fetch() within your actions to GET and POST data from your API - do not use jQuery methods

8. Your client-side application should handle the display of data with minimal data manipulation

Project Overview

My application has a vacation index page with a list of upcoming trips; you can either create a new trip from there, delete a selected trip, or click one of the existing trips to view its itinerary page. Inside each vacation’s itinerary page displays day “cards” for however many days your vacation is set for, and all the activities input for the specific vacation. Activities will either appear inside a set day or, if unassigned a day, will display in the activities list section at the bottom of the page. Users are able to toggle activities between days easily via a select dropdown and allows for a visually pleasing experience. There’s an “Add Activity” button that allows users to input a new activity at the nested route vacations/:vacationId/activities/new for the specific vacation as well.

Rails Models:

React Components:

I made sure to import the necessary components at the top of the App.js file to set different routes for my web application.

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';

The following is my render function in the App.js file to allow for my different route pages by using <Switch> to only display one at a time:

render() {
if (this.props.loading) {
return (
<h3>Loading...</h3>
)
}
return (
<ThemeProvider theme={theme} >
<Router>
<Layout>
<Switch>
<Route exact path="/" component= { Home } />
<Route exact path="/vacations" component={ VacationList } />
<Route exact path="/vacations/new" component={ VacationForm } />
<Route exact path="/vacations/:vacationId" component={ VacationShow } />
<Route exact path="/vacations/:vacationId/activities/new" component={ ActivityForm } />
<Route component={ ErrorPage } />
</Switch>
</Layout>
</Router>
</ThemeProvider>
);
}

Video Demo

Redux and Redux Thunk

In order to use Redux, you need to import Provider and createStore into your index.js file. If your application uses asynchronous requests to create, read, update, or delete (CRUD) data stored in your database, you also need to import a few more dependencies to use: applyMiddleWare and thunk . I’m additionally using the combineReducers function because I have two reducers, but it’s unnecessary if you only have one.

import { Provider } from 'react-redux';import { createStore, applyMiddleware, combineReducers } from 'redux';import thunk from 'redux-thunk';

Because I have two reducers, I combine my reducers like so:

const rootReducer = combineReducers({
vacations: vacationsReducer,
activities: activitiesReducer
})

Then create a store variable and assign the value of the createStore function with two arguments: (1) your reducer, and (2) the applyMiddleware function with thunk as its argument.

const store = createStore(rootReducer, applyMiddleware(thunk))

Finally, pass in the Redux store as a prop inside the <Provider> component, like so:

ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);

Closing Remarks

Having a global store using Redux, handling asynchronous calls to the API with Redux Thunk, passing down component states as props… all of it was initially overwhelming but with a little practice, everything clicked and React became really fun. I now understand the high regards for the JavaScript Library!

--

--