Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for uppercased action type name in createActions returned action map? #328

Open
devmonkey22 opened this issue Oct 2, 2018 · 1 comment

Comments

@devmonkey22
Copy link

I'm new to redux-actions, but I was trying to find a way to reduce boilerplate on both creating my actions and handling the actions in reducers, which typically need the action names defined separately.

There are probably several ways to handle this, but I was hoping that because createActions is already given a dictionary of actions/namespaces and creates the actions with function's whose toString() is already assigned to the actual action type name, it could also return a 2nd dictionary key (say, as uppercase since the action function is forced to lowercase) that holds the name of the action. Otherwise you'd have to use something like action.toString() which is ackward.

Perhaps its another property for options like emitActionNames that handles this?

The example that comes to mind is https://github.com/afitiskin/redux-saga-routines, where they define the fetchData.TRIGGER property as the action type name and fetchData.trigger() as the action creation function.

My workaround after calling createActions was calling the following:

/**
 * For a given action map (defined by redux-actions createActions()), create an analogous uppercased property that contains the lowercased action's 'type' value
 *
 * For example, given an action map like:
 *      {
 *          todos: {
 *              fetch: function() { ... }
 *          }
 *      }
 *
 * It will return the map like:
 *      {
 *          todos: {
 *              fetch: function() { ... }
 *              FETCH: 'TODOS/FETCH'
 *          }
 *      }
 *
 * that can be used with reducers, sagas, etc.  This saves writing boilerplate to create the action type names in a separate structure.
 *
 * @param actionOrNamespace
 */
export function setActionMapNames(actionOrNamespace) {
    Object.entries(actionOrNamespace).forEach(
        ([key, value]) => {
            if (typeof value === 'function') {
                // Add uppercase version of action to specify action type
                // redux-actions exposes action 'type' as function's string
                actionOrNamespace[key.toUpperCase()] = value.toString();
            }
            else {
                // Must be another namespace
                setActionMapNames(value);
            }
        }
    );
    
    return actionOrNamespace
}

So as before, you would dispatch the action like:

dispatch(actions.todos.fetch());

Then in a reducer, you can refer to it like:

function reducer(state,action) {
switch (actions.todos.FETCH) {}
}

Thoughts on adding something like this? Maybe its already there somewhere and I didn't see it... if so, my apologies.
Thanks!
Mike

@simondell
Copy link

As well as createAction(), redux-actions includes handleAction() and handleActions() for creating reducers that respond to specific actions. You can pass the functions created by createActions() to both the handleAction(s) functions and they will return you a reducer which has the same behaviour as the switch/case.

import { createActions, handleActions } from 'redux-actions`

const myActionCreator = createAction('FOO/BAR')

const defaultState = 'whatever you need'
const myReducer = handleActions({
  [myActionCreator]: (state, action) => { /* return updated state */ }
}, defaultState )

Take a look at the docs for more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants