Spencer FengSpencer Feng

Authentication in React Apps with JWT: Part 2

This is the second part of our ‘Authentication and Authorisation in React Apps with JSON Web Tokens’ series. In this part, we will complete following tasks:

  • Set up Redux
  • Create pages
  • Set up React Router

Set up Redux

Redux is a predictable state container for Javascript app. In our React app, we will use it to track different states in our application. For example, it can tell us if there is a logged-in user or not.

First, we need to install ‘redux’ and ‘react-redux’ in our React app (in the ‘client’ directory).

$ npm install --save redux
npm install --save react-redux

Then, we need to import them to ‘client/src/index.js’ file.

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

Then, we will create reducers. Create a new file in ‘client/src/reducers.js’ and paste the code below to it:

export const cUser = (state, action) => {

    switch (action.type) {
        case 'SET_USER': 
            return Object.assign({}, action.data, {});
        default:
            return state || {};
    }

}

This reducer is used to update the ‘cUser’ state in our application which tells us if there is a logged-in user or not.

Then, we need to import it to the ‘client/src/index.js’ file:

import * as reducers from './reducers';

Then, in the ‘client/src/index.js’ file, we need to create our Redux store and make our React app respond to the change of Redux state, so that when a user logs in, the app will be re-rendered to show some related information or vice versa.

Let’s replace the code below:

ReactDOM.render(<App />, document.getElementById('root'));

with:

// Create the store
const store = createStore(combineReducers({
    cUser: reducers.cUser
}));

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

function init() {
    run();
    store.subscribe(run);
}

init();

Create pages

In this app, we need a signup page, a login page and a home page and all these pages will share the same top navigation bar. We are going to create a React component for each of these 3 pages and a component for the shared top navigation bar. All these 4 components are located in the ‘client/components’ directory. Please grab the code for these 4 components from the links below:

Set up React Router

In this section, we are going to use the new React Router 4 to link all those page components together in our app.

First, we need to install ‘react-router-dom’ which is the react router for web, ‘react-router-redux’ and ‘history’ which is used by ‘react-router-redux’. For more information, please refer to its official GitHub Repository.

$ npm install --save react-router-dom
$ npm install --save react-router-redux@next
$ npm install --save history

Then, we need to import them to the ‘client/src/index.js’ file:

import createHistory from 'history/createBrowserHistory';
import { ConnectedRouter, routerReducer, push } from 'react-router-redux';

Then, we need to create a history that our router will use in the ‘client/src/index.js’ file. Please make sure, this line of code is added before the run() function is defined, since we need to use it in the run() function.

// Create a history of your choosing (we're using a browser history in this case)
const history = createHistory();

Then, we update our run() function to:

function run() {
    ReactDOM.render(<Provider store={store}>
        <ConnectedRouter history={history}>
            <App store={store} />
        </ConnectedRouter>
    </Provider>, document.getElementById('root'));
}

Now, we need to go to the ‘client/src/App.js’ file to specify our routes and assemble all the components together. Please replace all existing code in file with the code below:

import React, { Component } from 'react';
import Navbar from './components/Navbar';
import { Route, Switch } from 'react-router-dom';
import HomePage from './components/HomePage';
import LoginPage from './components/LoginPage';
import SignupPage from './components/SignupPage';

class App extends Component {
    render() {
        return ( 
            <div className = "App" >
                <Navbar />
                <div className="container">
                    <Switch>
                        <Route path="/login" component={LoginPage} />
                        <Route path="/signup" component={SignupPage} />
                        <Route path="/" component={HomePage} />
                    </Switch>
                </div>
            </div>
        );
    }
}

export default App;

Great, we have completed all the tasks in the second tutorial of our series. In the next tutorial, we are going to do some work on the server side.

View the source code for this tutorial on GitHub.

Please sign up to our Newsletter if you want to get notified when new tutorials are available.

×