Rick Glascock
3 min readMay 5, 2020

--

I’m working on a React project that will serve as a management site for an extended family summer property shared by 40 members. The site includes scheduling of cabins, the ability to produce maintenance tickets as well as an admin panel that allows managers the ability to approve reservations and followup on requests. The backend is built on Rails.

This is the first time I’ve implemented Redux in a React project and I had high hopes that creating a Redux store would allow me to easily access data in a centralized location instead of making repeated unnecessary fetches to the API.

npm install redux
npm install react-redux

After getting the my store initialized and setting up some basic actions and reducers to save data from my initial fetches into the store, I found accessing the data in my class based components to be a fairly straight ahead process:

  • Import the ‘connect’ method form the react-redux package into the component.
  • Set up a mapsStateToProps function that does exactly what it says, takes data from the redux store and makes it available as props to the component.
  • Wrap the component in the ‘connect’ function passing mapStateToProps as an argument.
import { connect } from ‘react-redux’;class UpdateProfile extends Component {
render() {
return <div className="container"></div>
}
}
const mapStateToProps = state => {
return {
curUser: state.users.curUser
}
};
export default connect(mapStateToProps)(UpdateProfile);

Having a single source of truth for a larger app has some advantages in that you avoid long, downward trails of props found in non redux React apps. In addition, using CombineReducers allows you to change how your Redux store is organized in one convenient spot.

Sounds perfect, right?

Well, all is well until I began to set up some private routes in order to wall off my content from unauthenticated users. The method I was using included creating a PrivateRoute functional component that is rendered via the main Router and accepts as a prop a particular component.

App.js
<Switch>
<PublicRoute restricted={false}
exact path=’/’ component={Home} />
<PublicRoute restricted={true}
exact path=’/login’ component={Login} />
<PublicRoute restricted={true}
exact path=’/newuser’ component={NewUser} />
<PrivateRoute exact path=’/schedule’
component={ScheduleContainer} />
<PrivateRoute exact path=’/maintenance’
component={MaintenanceContainer} />
</Switch>

The PrivateRoute checks to isLoggedIn (whose state is set in Redux store at time of authentication) and then redirects back to intended route if true.

import React from ‘react’;
import { Route, Redirect } from ‘react-router-dom’;
import {useSelector} from ‘react-redux’;
const PrivateRoute = ({component: Component, …rest}) => {
const isLoggedIn = useSelector(state => state.users.isLoggedIn)
return (// Show the component only when the user is logged in// Otherwise, redirect the user to /signin page<Route {…rest} render={props => (
isLoggedIn ? <Component {…props} />
: <Redirect to=”/login” />
)} />
);};export default PrivateRoute;

At this point, I discovered one of the weaknesses in using Redux. It was designed to work with class based components, not functional based. How to retrieve isLoggedIn state from the store in a functional based component?

Enter React Hooks…

React Hooks were designed to simplify the traditional React props flow, but recently the React team has added the “useSelector” hook which allows you to access Redux store from a functional based component.

“The selector is approximately equivalent to the mapStateToProps argument to connect conceptually. The selector will be called with the entire Redux store state as its only argument.”

Using “useSelector” I was able to easily access my isLoggedIn state from Redux store to verify authentication and re-route my user. A very helpful tool in the React/Redux arsenal indeed.

--

--

Rick Glascock

After years of teaching music in Austin, Shanghai and Yangon, I’m making a career change to my other passion, software development.