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 082018

Taking off Wednesday thru Sunday – really looking forward to some vacation! Well, vacation from my day job. I’ll probably still do some DevLifts open source work ????????

What I’ve done

Today I got a lot of smaller UI components hooked up to the API at work – so we’re getting really close to launch.

Today I Learned

React’s setState accepts a callback!

Interesting Links

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

Worklog 080918

What I’ve done

Today I fought with an issue all day where I was trying to pass some class functions from a Container component down to a dumb component via the Context API, but I couldn’t use the functions that call this.setState because you can’t call setState in a render. I still haven’t come up with a great solution — I ended up just converting the dumb component to a smart component.

This isn’t the architecture I came up with — all the data should live in the feature Container and get passed down. I need to write more in-depth on this issue at some point — maybe someone has a solution.

This morning I also paired with Kurt Kemple, a maintainer of GatsbyJS, and got a walkthrough of how Gatsby works (and how I can make my first commits to the project ????). Looking forward to it!

Today I Learned

destructuring nested objects!

Interesting Links

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

Worklog 080618

Over the weekend and this morning, I finished implementing the new state architecture so we are now using Redux for global state and each feature has a container that holds the state for the feature and passes it down via Context. I did put the feature state into Redux, but that may have been a mistake. I may undo that and bring it back to be local state for the feature container.

Thad and I also got a lot done for DevLifts — fitStart month 2 plans started going out, we ran some numbers to see how the past month went with web traffic, and we implemented some neat new discounts. ????

Today, I spent a lot of time thinking about our component tree and refactoring all the code I had written for my new feature at Trinity. I also started [finally] writing new components — hoping to finish the UI tomorrow and Wednesday and then go back and make it all stateful. 

Today I Learned

There’s no great way to delay the unmounting of a React component…

I needed to make a Loading component show for at least 2 seconds, even if the data was already back from the API and loaded into the store. Weird, I know, but it was a UX requirement and there’s actually a business case for it in our particular instance.

I reached for componentWillUnmount and quickly figured out that the component is still going to unmount and there’s no way I can really stop it from doing that in componentWillUnmount.

I ended up doing something really hacky: I set a loading state in the feature container, and then set up a function to create a Promise and resolve it after 2 seconds. When I need that loading component to render, I just set the loading state to true and then fire the Promise function. When it resolves, it sets the loading state back to false.

Stupid, I know. But it worked.

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:

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 061918

Started my new job at Trinity Apparel today as a Junior Frontend Engineer. I’ve been looking to get back into the habit of writing, so I’ve decided to share “worklogs” so I can keep up with my progress over time and have something to look back on next time Imposter Syndrome™️ inevitably sets in.

Not much went on today other than typical “drink from the fire hydrant” learning as well as a 1 on 1 with my boss and a Sprint Meeting. My big task over the next couple of weeks is to learn more about Webpack (and other build tools) and see how we may be able to use modern tooling (so I can write in ES Next syntax) but still be able to build my React components and inject them into an existing PHP monolith without touching the production build process at all.

It sounds super abstract, and I may not even be describing the problem in nearly the amount of detail I need to, and that’s partly because I haven’t wrapped my head around the full scope of the problem. I’m writing this anyway primarily because I want to re-establish my habit of writing that I’ve lost over the past year.

Will share more as I learn more, but in the meantime, if you have experience integrating React into a specific part of a [mostly] server-rendered PHP monolith, I’d love to hear your thoughts or read any links you’d like to share.

J