npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

make-action-creator

v0.4.1

Published

Make action creators enhanced for async control flow.

Downloads

459

Readme

make-action-creator

js-semistandard-style Build Status npm version

Context

Actions

Actions are one of the most important part of a react/redux application. Also they're the most simple ones: plain objects acting like messages (signals) telling what's going on in your application.

{
  type: 'MY_ACTION',
  payload: 'foo'
}

Actions Creators

So the action object is very simple, just need a unique identifier (the type field). By convencion, the type should be an uppercase string. You want to be sure that you dont misspell the action type when dispatch an action, and because of that, the redux documentation encourage you to make a function to return always the same action type: the action creator function.

const myAction = payload => ({
  type: 'MY_ACTION',
  payload
})

myAction('foo');

Action Type Constant

Now you have the action creator, but you need the action type in the reducer to generate the new state. So you'll need a constant to be sure you are using the same action type in the action creator an the reducer function.

function myReducer(state = initialState, action) {
  switch (action.type) {
    case MY_ACTION:
      return 'My new state'
    default:
      return state
  }
}

Action Creator Creators

This sounds like an Andre Staltz What The Flux joke (https://www.npmjs.com/package/wtflux) but actually make sense. In real world applications you have a lot of related actions in async operations (e.g. data fetch). You'll end up with a lot of costants imports (FETCH_CLIENTS , FETCH_CLIENTS_START, FETCH_CLIENTS_SUCCESS, FETCH_CLIENTS_FAILURE, etc), and of course, the corresponding action creators. This module is an Action Creator Creator (lol) that tries to keep the related actions and constants together in a single object.

My redux application goals

There are many diferents ways to do a redux application. Regardless this module is just about the actions stuff, I use it in a redux application context with this assumptions:

  • Actions are simple signals
  • Reducer functions must express the state transformation, not the actionCreator.
  • Action creator must be as pure as the reducer.
  • Side efects in redux sagas.

Usage

Simple actions

In your actions file

import makeActionCreator from 'make-action-creator';

export const showModalForm = makeActionCreator('show_modal_form');

In your componant file

import showModalForm from './actions';

dispatch(showModalForm(data));

/*
{
	type: 'SHOW_MODAL_FORM',
	payload: data
}
*/

In your reducer file

import showModalForm from './actions';

function myReducer(state = initialState, action) {
  switch (action.type) {
    case showModalForm.type:
      return 'My new state'
    default:
      return state
  }
}

Async flow

In your actions file

import makeActionCreator from 'make-action-creator';

export const deleteUser = makeActionCreator('delete_user');

In your componant file

import deleteUser from './actions';

dispatch(deleteUser(userId));

/*
{
  type: 'DELETE_USER',
  payload: userId
}
*/

In your sagas file :)

import deleteUser from './actions';

function * deleteUserWorker (action) {
  yield put(deleteUser.start(action.payload)); // dispatch 'DELETE_USER_START'

  const { user, error } = yield call(userApi.delete, action.payload);

  if (error) {
    return yield put(deleteUser.failure(error)); // dispatch 'DELETE_USER_FAILURE'
  }

  yield put(deleteUser.success(user)); // dispatch 'DELETE_USER_SUCCESS'
}

export function * deleteUserWatcher () {
  yield takeEvery(deleteUser.type, deleteUserWorker); // whatch 'DELETE_USER'
}

In your reducer file

import deleteUser from './actions';

function myReducer(state = initialState, action) {
  switch (action.type) {
    case deleteUser.START:
      return 'Deleting user...';
    case deleteUser.FAILURE:
      return 'doh!'
    case deleteUser.SUCCESS:
      return 'Done!'
    default:
      return state
  }
}

Integrate with react-redux-spinner

I kinda like this module: https://www.npmjs.com/package/react-redux-spinner.

As async flow use to come with showing some loader in the page, if you are using this module and like the async related actions to include the flags to start and finish the react-redux-spinner, just add this to the actionCreator creation step:

const myAction = makeActionCreator('my_action', { rrSpinner: true });

Add more data to the action object

By default you just pass one paremeter to the action creator and that will be the action payload. If you want to add extra data:

const myAction = makeActionCreator('my_action', { rrSpinner: true });

myAction('foo', {
  more: data
})

/*
{
  type: 'MY_ACTION',
  payload: 'foo',
  more: data
}
*/