0.1.3 • Published 4 years ago

react-usereducermap v0.1.3

Weekly downloads
2
License
MIT
Repository
github
Last release
4 years ago

react-usereducermap

A React.useReducer replacement that maps one or more handler functions to an action.

Example

import React from 'react';
import { useReducerMap } from 'react-usereducermap';

export default function HelloWorld() {
  const [state, dispatch] = useReducerMap(
    {
      a: (state, data, meta) => {
        return { hey: 'I got called' };
      },
    },
    {}
  );

  return (
    <div className="App">
      <h1
        onClick={(evt) => {
          dispatch({ type: 'a', data: 'this is some data' });
        }}
      >
        Hello react-usereducermap
      </h1>
      <pre>{JSON.stringify(state, null, 2)}</pre>
    </div>
  );
}

Install

npm i react-usereducermap

Import

import { useReducerMap } from 'react-usereducermap';

Construction

const [state, dispatch] = useReducerMap(actionMap, initialState);

Dispatching

The dispatch function is the same one returned from useReducer.

The dispatched object must have a type property that will be mapped to the action handler. Objects missing a type will throw an error indicating that no handler was mapped to the action. Warning: I may add validation on the type later to provide a more specific error message.

ActionMap

An object where the keys are actions that are dispatched through the reducer and values that are the handlers.

function actionHandler(state, data, meta) {
    // does something
    // returns the modifications to the state
    return { newStateVal: "Hey hey!!" };
}

function anotherActionHandler(state, data, meta) {
    // does something
    // returns the modifications to the state
    return { newStateVal: "Hey hey!!" };
}

const actionMap = {
    // Single action handler
    OnClick: actionHandler,
    // multiple action handlers, executed sequentially
    OtherClick: [actionHandler, anotherActionHandler],
    // multiple action handlers with helper data and functions.
    // Helpers are added to the handler's meta object as they are named. Don't overwrite dispatch or type.
    yetAnotherClick: [actionHandler, [anotherActionHandler, { someData: 'extra data', otherFunction: ()=>{}}]],
    // Called on all events before action handlers
    pre: (state, data, meta) => {},
    // Called on all events after action handlers have executed
    post: (state, data, meta) => {},
}

const [state, dispatch] = useReducerMap(actionMap, {});
dispatch({type: 'OnClick', ignoredData: "I'm not being used"})

console.log(JSON.stringify(state, null, 2))
/* Results:
{
    "newStateVal": "Hey hey!!"
}

ActionHandler

function actionHandler(state, data, meta) {
  // does something
  // returns the modifications to the state
}
  • state: The reducer's current state object.
  • data: The remaining attributes of the dispatch.
  • meta: An object containing the original action type, dispatch function for the reducer, and extra helpers.
// data example
// If dispatch were called like this:
dispatch({ type: 'OnClick', ignoredData: "I'm not being used" });
// Then data will contain
{
  ignoredData: "I'm not being used";
}
// meta example
// If dispatch were called like this:

dispatch({type: 'OnClick', ignoredData: "I'm not being used"})
// Then meta will contain this:
{
    type: 'OnClick',
    dispatch: dispatch // original dispatch function
}

The function returns a state that shallow merges into the original state.

You can dispatch from an action handler. You can cause infinite loops, so watch out!

Reserved Action Handlers

  • pre: Executed before all other action handlers.
    • Only one pre handler and must be a function
    • Can modify state
    • meta object does not contain the dispatch function.
    • Dispatching an object like {type: 'pre'} will throw an exception.
  • post: Executed after all other action handlers.
    • Only one post handler and must be a function
    • Can modify state
    • meta object does not contain the dispatch function.
    • Dispatching an object like {type: 'post'} will throw an exception.
  • patterns: Not implemented yet
    • Maps a regex to a set of action handlers
    • Evaluated after explicit action handlers
    • Good for handling events with a common prefix. Like if all your API callers will prefix an error action like {type: 'ERROR_API_GETHOST'} and {type: 'ERROR_API_GETUGLYPHOTO'}, then you can have a regex like /^ERROR/ and handle the API errors in a common way rather than in an explicitly named action handler for each.
    • Throws a TypeError if you try to use it.
    • Dispatching an object like {type: 'patterns'} will throw an exception.