Namespacing Redux Action Type Constant Values

Most everyone agrees that defining constants for your Redux action types is good idea. If you use string literals, it’s all too easy to misspell one and wonder why your reducer isn’t responding. If you use a constant, your IDE can point out that gaffe right away.

Here’s an example from the Redux documentation:

export const ADD_TODO = 'ADD_TODO'
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'

Since it’s in the docs, this is how most projects you see implement them. So, you’re asking, is there any reason to do it differently? Yes, there is.

In any non-trivial app, you’ll probably define action type constants and the action creators that use them in several different files, separated by functional area. Different team members may be adding to them all the time., so an action type constant in one file conflicting with one in another file is always a possibility.

For instance, consider the constants defined these two files:

articles.actions.js

export const FETCH_REQUESTED = 'FETCH_REQUESTED'
export const FETCH_COMPLETE  = 'FETCH_COMPLETE'
export const FETCH_ERROR     = 'FETCH_ERROR'

profiles.actions.js

export const FETCH_REQUESTED = 'FETCH_REQUESTED'
export const FETCH_COMPLETE  = 'FETCH_COMPLETE'
export const FETCH_ERROR     = 'FETCH_ERROR'

If your action types are defined in separate files, chances are the reducers that respond to them are as well. When you combine your reducers, you essentially create one big switch statement, and if you have two action types with the same constant value, the wrong case block will eventually be fired for one of them.

Is the answer to make the constant names and values longer?​

export const FETCH_PROFILES_REQUESTED = 'FETCH_PROFILES_REQUESTED'
export const FETCH_PROFILES_COMPLETE  = 'FETCH_PROFILES_COMPLETE'
export const FETCH_PROFILES_ERROR     = 'FETCH_PROFILES_ERROR'

Possibly, but it’s overly verbose and unnecessary.

Remember, the constant name and value need not be the same. Here’s a good way to namespace your constant values while keeping the names simple and clear within the context of their use.

articles.actions.js

export const FETCH_REQUESTED = 'articles/fetch-requested'
export const FETCH_COMPLETE  = 'articles/fetch-complete'
export const FETCH_ERROR     = 'articles/fetch-error'

profiles.actions.js

export const FETCH_REQUESTED = 'profiles/fetch-requested'
export const FETCH_COMPLETE  = 'profiles/fetch-complete'
export const FETCH_ERROR     = 'profiles/fetch-error'

In the articles reducer, we know we’re dealing with articles, so all the constants don’t need to have ARTICLES as part of the name. Same with the profiles reducer.

articles.reducer.js

import { FETCH_REQUESTED, FETCH_COMPLETE, FETCH_ERROR } from '../actions/articles.actions'

profiles.reducer.js

import { FETCH_REQUESTED, FETCH_COMPLETE, FETCH_ERROR } from '../actions/profiles.actions'

That’s it. Simple constant names with namespaced values will give you clarity and reduced verbosity, while ensuring the right cases fire in your reducers.

Leave a Reply

Your email address will not be published. Required fields are marked *