React and Redux – Redux Flow

cory

Welcome to Part 8 of this comprehensive review and summary of Cory House’s Pluralsight course Building Applications with React and Redux in ES6.

Cory is a Microsoft MVP in C#, founder of OutlierDeveloper.com, avid tech reader, and speaker.

He believes in clean code, pragmatic development, and responsive native UIs.

Also in this series:

Part 1 – Introduction and Background

Part 2 – Environment Setup

Part 3 – React Component Approaches

Part 4 – Initial App Structure

Part 5 – Intro to Redux

Part 6 – Actions, Stores and Reducers

Part 7 – Connecting React to Redux

This Part describes the 9th module in the course, Redux Flow, which is a coding module.

Redux Flow

React Beginners

At the start of the course, Cory said you should have previous experience of React. Skip on to the next section if you have, because here I’ll explain some of React basics here so that beginners can follow along too.

Although you don’t have to use it, React is typically used with JSX. Look at this hello world fiddle: React Base Fiddle

In this example there is an HTML section and a JavaScript section.

The HTML is just an empty div. All of the magic happens in JavaScript. The render function returns your view code, this is JSX code and it gets converted into HTML. The JavaScript adds the props name “World” onto the end of “Hello “.

Experiment with different tag names and values to understand.

In this course we use JSX because it is more readable than the alternative. Here’s the hello world example without JSX.

Facebook have a beginner’s tutorial available to teaches you how to build a simple but realistic blog comments box.

Also see other Plurasight courses as explained in Part 1.

Create Simple Add Course Form

We start by adding a constructor to our CoursesPage class, and this sets the state the constructor.

In the render() function we return our view, containing our headings and input textboxes.

We add two new functions: onTitleChange and onClickSave

Binding in ES6

We run up our app and see a couple of errors, which Cory explains how to fix.

As mentioned in Part 3, we have to handle binding ourselves when using ES6.

Cory explains that we are getting the wrong this – it needs to be an instance of our component, not the input!

As a fix, we see that we can set these correctly in our constructor, by binding this.onTitleChange and this.onClickSave to the this of our CoursesPage component.

As described in Part 3, there is an alternative approach but that has an impact on performance.

Actions

It’s time to begin setting this up with Redux. First we create a new actions directory with courseActions.js

In this file we create an action creator.

We also see a nice new feature in ES6 – no need to repeat yourself with e.g. courses: courses

Reducers

Here we create our first reducer. We create a new reducers directory and add coursesReducer.js.

You are not obliged to add “Reducer” to the end of the file name – from Cory’s commentary on naming convention, your own preference is going to be somewhat dependent on what your preferred editor happens to be.

The next religious issue of named vs anonymous functions immediately comes up. I used to prefer anonymous functions but at some point in Kyle Simpson’s (highly recommended) Advanced JavaScript course he gives three good reasons in favour of named functions.

Cory begins with bad mutable code, and then replaces it with the ES6 spread operater and Object.assign.

Don’t worry if you haven’t used ES6 before because Cory explains this here.

Finally Cory discusses possible alternatives for switch statement allergics.

Root Reducer

Redux supports multiple reducers and most apps will use them, so here we learn how to create a root reducer.

We start by importing combineReducers from Redux, and use ES6’s beautiful shorthand property names for nicely terse yet expressive clean code.

Store

We start by creating a store directory with configureStore.js

Cory uses an initialState argument in the configureStore function, and mentions that this can be useful for server side rendering.

I think server side rendering is an important topic because it has significant affect on search engine optimization. Not the focus of this course but at least something worth baring in mind and good to know.

The function that we return is createStore.

Next we add middleware, and this require us to first import applyMiddleware. This allows us to pass applyMiddleware() into our createStore function.

We also import redux-immutable-state-invariant and use it as the argument in our applyMiddleware function.

Using Cory’s react-slingshot you can see how to configure additional pieces of middleware.

Instantiate Store and Provider

We start with our imports. Cory explains that this should include Provider from ‘react-redux’, which is a higher order component that attaches our store to our React container components.

We wrap our Router component inside of our Provider component.

Now there’s just one piece of plumbling left to do…

Connect Container

In coursesPage.js we import connect from ‘react-redux’.

We also update our export, so that we return our CoursesPage object as a parameter to the call to connect.

We see the functional programming technique of taking the results of one function and passing it into the next, all in the same line of code.

connect usually takes two arguments: mapStateToProps and mapDispatchToProps, but mapDispatchToProps is optional and we don’t use this yet.

We also create our onClickSave function here. Cory shows us the “ugly” way of dispatching actions here, but we’ll see a more elegant way soon.

Step Through Redux Flow

We update the render function to display the correct list of courses, using new function courseRow to displays the course title.

When we’re happy we run ESlint with:

npm start -s

We see and fix our linter errors: a missing semicolon and missing props validation.

From 3:55, we set breakpoints in each function of interest, and Cory explains how it is all working together.

mapDispatchToProps Manual Mapping

There is a cleaner way to code this, using mapDispatchToProps.

We add a reference to mapDispatchToProps into our connect function, and write our mapDispatchToProps function.

Here Cory does the mapping manually so that we can see what is going on more clearly. It maps the action createCourse using an anonymous ES6 arrow function:

createCourse: course => dispatch(courseActions.createCourse(course))

With this work done we can now simplify our onClickSave function.

At 2:55 we run npm start again, and fix linter errors.

Cory explains that as  we’ve defined our mapDispatchToProps function, dispatch is no longer injected as a property. connect no longer adds a dispatch property on our component. This means we can remove our props validation on dispatch.

bindActionCreators

Cory says our call to mapDispatchToProps is still quite verbose.

In coursesPage.js, we import bindActionCreators from redux. We can now replace our anonymous ES6 arrow function with

actions: bindActionCreators(courseActions, dispatch)

Cory explains that an alternative implementation would be

course: bindActionCreators(courseActions.createCourse, dispatch)

We also see how the propTypes need to be updated

Container Structure Review

That has been a lot of detail. Now we take a step back to review the 5 major pieces of a React component when using Redux:

  1. The constructor
  2. child functions which are called by render
  3. render function
  4. propTypes with our propType validation
  5. Redux connect and related functions

Action Type Constants

Cory explains the magic strings are typos waiting to happen, and discusses some different implementation options for creating constants.

In this example we add actionTypes.js, and in courseActions.js we add

import * as types from ‘./actionTypes’;

We use similar code to access these constants from courseReducer.js

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s