Where does your business logic go in a React/Redux app?

**This is a cross-post from my newsletter, Fitness && Functions.

After my last email mentioning Redux middleware, reader David Davis asked me about how this works in a React/Redux application.

I know it’s 2018 and Redux is dead and OMG why aren’t you just using React Context or Apollo and blah blah blah, and while I certainly agree that a lot of what Redux does for you is getting implemented into React itself, I’m thinking some of the people who love to hate Redux may only hate it because they’ve been using it wrong.

It seems many have been sprinkling their business logic in reducers, components, and even actions. But this is a recipe for having hard-to-reason-about code.

Straight from the Redux Docs:

…actions are just plain objects

Reducers are just pure functions

The solution has been there all along, but I don’t think enough of us knew about it or really understood it: Redux Middleware.

[Redux Middleware] provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.

This is where your business logic should go!

Over the next few emails, I’ll share some examples of how to get up and running with Redux Middleware, but in the meantime: does this make sense to you? If you’ve used / are using Redux, where does your business logic live?

Worklog 091018

I did that thing again where I went a bit without writing a worklog. Man it’s tough to stay consistent sometimes. It’s easy to fall into not prioritizing things even though you know they’re really helpful (like these worklogs).

What I’ve done


I started organizing Notion for our company. I signed us up a couple of months ago and have been slowly adding a few things here and there. I’m trying to find a good organization that will work for the team and ensure that everyone (no matter if it’s their first day or their 1000th) can find out anything they need to know about the company.

I sat in on a call with a new vendor this morning.

I also worked on our company positioning statement.

This afternoon, I worked on setting up custom exception logging with Sentry. We now have nicer errors when something goes wrong with any API calls. ????


This morning I got all my tasks and appointments organized for the week, shipped some small changes for a freelance project, and made my FitLog for today.

What I’m working on


I’m continuing to work on interviewing high-level execs so I can refine our positioning statement.


Tonight I’ll be working on a freelance project with Rails. I’m working on building out a 2m+ record searchable database with Rails and Elasticsearch. That’s a first for me, so I’ll write about how it goes this month!

Today I Learned

Sentry’s Raven.js is actually on its way out, it seems. It still gets support and bug fixes, but new features are being added to the npm packages.


Interesting Links

Here’s a few links to things I’ve read, watched, or listened to:

Worklog 080318

What I’ve done

Today I mostly worked on refactoring — but I did start implementing a new state management architecture. Inspired by this post I found on Medium, this is what I came up with:

For each feature, we’ll have a container that is responsible for retrieving data from our store as well as storing data into it. It may also have some local state that will be needed feature-wide. We’ll then create a Context using React’s new Context API (new in 16.3) and use that to pass data down to whatever components we need to.

This way, we get the benefits of Redux to share state that’s needed across the whole app, as well as less of the Redux boilerplate that comes along with shoving everything into Redux. Using the Context API, our dumb components can easily grab whatever props they need without prop drilling.

This setup feels great to me. Tyler, my frontend colleague, felt good about it too. I’ll post an update in the future after it’s implemented to share how it’s working for us.

I also set up Continuous Integration with CodeShip today.

What I’m working on

I’m currently still working on the above, as well as continuing to research how to automatically keep Rails API docs up to date (and how to keep sample data automatically in sync with my json-server mock API — thoughts appreciated!

Today I Learned

Had a lunch and learn with my chief architect — learned all about Microsoft’s history of trying to force people into upgrade cycles so they could sell more software, and how they tried to kill the open web and create their own private web so they could create a cash-producing ecosystem where they would have gotten paid for Visual Studio to write web code, paid for web hosting to allow the page to live on MSN, and power to control who and what got to be discovered. Yikes. ????

I also learned more about metaprogramming, a concept I was only vaguely familiar with (and still need to do some further reading on), and we also discussed functional programming concepts in depth. I’ve been learning a lot about functional programming in JavaScript over the past year, so it was great to hear that I’m on the right track.

Lastly, I learned that you can rename variables as you destructure them from objects today! ????????

Interesting Links

Here’s a few links to things I’ve read, watched, or listened to:

Worklog 073018

Happy Monday!

What I’ve done

Friday, I finished all the documentation for our new React environment I’ve set up at my day job. It was a new experience to think through how to best present documentation for lots of different types of people who may be looking at my repo (now or in the future). I’d love some feedback so I can learn to write better documentation.

Over the weekend, I watched some videos on testing Javascript and Redux with Jest, and I finally made a little headway on the Fit CLI project we’re getting off the ground at DevLifts!

What I’m working on

Today, I’ll mostly be working on building out components for the feature I’m supposed to ship within the next couple of weeks at Trinity. Most of the day will probably be spent pairing with the other frontend dev.

This evening, I’ll probably also work on a few things for DevLifts:

  • UX Review of our existing site (we’re getting ready to start a design system)
  • Set up payment re-try settings in Stripe (for failed membership charges)
  • Set up new MailChimp automation to get testimonials from members having a good experience and to notify me to reach out directly if someone is having a bad experience

And at some point today I have to get a quote out to a client for a new project.


Right now, I mostly feel blocked just by the sheer amount of things going on. If I can get past my own mental fog, I’ll be golden.

Interesting Links

Here’s a few links to things I’ve read, watched, or listened to:

How to set up a React project without Create React App — Step 2: Initializing the Project and Installing React

Initializing the Project

After you’ve installed Node, the first step is to set up a new project. In your shell, navigate to a directory where you want to create a project. Then, run:

mkdir your-project-name && cd your-project-name

This will create a directory for your project (the first command) and then navigate into that new directory (the second command). If you’re new to the shell, the && operator can be used to run both commands, one after the other. You can chain together the && for as many commands as you wish.

Now that you’re inside your new project directory, you can run npm init to initialize the new project. It will ask you for a few pieces of data such as the version number of your app, a description, etc. You can always change these things later, so don’t sweat it too much. If you’d prefer to keep everything as the default value, simply run npm init -y.

Once this is finished, you’ll have a new file inside your directory: package.json. This file is basically a giant JavaScript object that keeps different pieces of information about your application. It’s used for a lot of things, but the most important things to pay attention to for now are the scripts, dependencies, and devDependencies keys. These are the main objects we’ll be adding to throughout the project.

Initializing the Git Repo

The next thing you’ll do is set up a Git repo for the project. First, create a new file .gitignore file with the following:

Next, run git init in your shell.  This will initialize the Git repository. Then you can run git add . to stage the files you’ve created so far, and git commit -m "initial commit" to make your first commit to the project.

In the next post I’ll outline how you can set up Parcel, the build tool I used for this project, and we’ll do a gut check with React to ensure everything is working.

How to set up a React project without Create React App — Step 1: Installing Node

Note: This series is based on React 16 — if you are using a newer version, your mileage may vary.

I was tasked without setting up a new codebase for a frontend rewrite at work this week. I’ve used Create React App for all my previous React projects, but I didn’t want to default to that — after all, stack decisions I make right now could affect the company for the next 3-5 years. I wanted to make sure I knew and understood all the pieces of this codebase since I’m responsible for it, so I decided to research different options and roll my own React environment.

With the speed at which everything changes in JavaScript-Land™️, I found it tedious to research all the tech I was considering and ensure that the sources I was learning from were not out of date, so I decided to write a post about how I set up a new React project without using Create React App. Everything is still somewhat in flux, so I will update this post if anything changes. Also, I would appreciate any feedback you’d like to share about my decisions!

How to Install NodeJS

Before you can set up a React project, you’ll need Node installed. While you aren’t necessarily creating a Node server here, Node is still used to add third party packages (via npm, which is bundled with Node) to your project as well as run scripts such as a local development server.

To install Node, you can take a couple of different routes.

Option 1: Install it from the NodeJS website. This will install a single version of Node on your machine as well as npm.

Option 2: Use a version manager like NVM or Nodenv. A version manager will allow you to install multiple versions of Node and switch between versions depending on the version required by the project you are working on. This is really helpful to utilize if you work on multiple JavaScript projects (or if you think you may in the future).

I chose to use Nodenv because it’s similar to rbenv, which I’ve used in the past. You can install Nodenv a couple of different ways, but I installed it via Homebrew because I’m on OS X and it’s dead simple.

After installing Nodenv, you can run nodenv install -l to get a list of available versions to install. You can then run nodenv install x.y.z (replacing x.y.z with your desired version number) to install the Node version of your choice. I chose 8.11.3, the version recommended on the NodeJS website at the time of this writing.

Therefore, I ran:

nodenv install 8.11.3

You should now have Node installed. In the next post, you’ll initialize your project and install React.

Worklog 062018 – New JavaScript Array Methods

Still lots of general setup-y stuff today, but I did learn a few things.

New JavaScript Array Methods

I was listening to this episode of Syntax on the way to work this morning, and learned some tasty new JS array methods.

I made a CodePen for code examples.

See the Pen JavaScript Arrays – .some(), .includes(), .from() by J.C. Hiatt (@jchiatt) on CodePen.dark


.some() tests whether at least one element in the array passes the test you provide as a callback function. Note that it immediately returns as soon as it finds the first true value, so it has no idea if there are multiple elements within the array that would pass true. It only cares that there’s at least one.


.includes() checks whether the array includes a specific value you pass in, returning true or false.


.from() creates a new array from an array-like or iterable object. Note that it only creates a shallow copy, so nested values aren’t copied. You can also pass in an optional map function to call on every element of the array as it is added.