Productive Redux

Dec 10, 2019

Redux is a powerful programming paradigm, but one of the most common criticisms is that it requires too much boilerplate code. For a long time, I agreed with that criticism: why would someone want to do so much work to get basic functionality?

I struggled with this question until I realized that I was thinking about it the wrong way. Saying Redux introduces boilerplate code is sort of like saying C introduces boilerplate – it’s that way by design.

That’s when I finally understood Redux. Before long, I built a simple framework that used Redux and automated away the majority of the boilerplate code that I was reluctant to write.

Motivating Use Case

Let’s use the canonical javascript example: we’re building a todo list. To do this, you need to do the following:

On the backend:

With this backend API set up, I’d then go back to my frontend codebase and

After repeating this process ~10 times, I realized that I didn’t really need so much fine-grained control. I didn’t need to call it id in one place and _id someplace else. And if I could just settle on a single way for defining attributes, I’d save myself a lot of time and my users a lot of bugs.

So I built a small library called Resource Creator that automated as much of this process as possible.

With Resource Creator

Use the createResource helper to bootstrap boilerplate everything:

// store/todos.ts

import { createResource } from 'lib/resourceCreator'

export const { actions, reducer } = createResource({
  resourceName: 'todo',
  collectionName: 'todos',
})

By doing this, you’ll get the following:

On the backend, define your resource:

# routes.rb
resources :lists

Then, create a controller that inherits from GenericObjectsController.

# todos_controller.rb
class TodosController < GenericObjectsController
  def resource
    Todo
  end

  def resource_params
    params.require(:todo).permit(:id,
      :title,
      :description,
      :done
    )
  end
end

And you’re done. Something that previously took an hour now takes 5 minutes.