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

react-context-reducer

v1.0.3

Published

React Context + useReducer = Hooks version of Redux. This library is intended to be a light weight stand-in for Redux.js built on top of reacts Hooks API.

Downloads

17

Readme

npm Build Status npm npm

react-context-reducer

React Context + useReducer = Hooks version of Redux. This library is intended to be a light weight stand-in for Redux.js.

Features

  • Same great features found in Redux
  • Create a data store using createContextReducer().
  • Simplify reducer complexity with combineReducers().
  • New combineActions() validate and consolidate all your actions into one export.
  • Use existing Redux middlewares or create your own.
    • Take advantage of the included reduxDevTools() or dispatchLogger middleware.
  • Use a simple <Provider /> HoC to register the context store with your app.
  • Connect your components to your stores state with connect() HoC, use() Hook,
  • Use getState() or dispatch() to interact with your store outside a react component.
  • Create as many stores as you need with createContextReducer() or use one super store by combining your reducers.
  • Only render when props change using React.memo().
  • Developer friendly with fail fast helpful debugging messages.
    • Use withTypeCheck() to describe your action and store shape.
  • Lightweight under 5kb in production

Installing

Using npm:

$ npm install react-context-reducer

Also install the required peer dependancies if you have not already done so:

$ npm install react
$ npm install prop-types

Core API

  • createContextReducer(ContextKey, reducer, middlewares) - Creates a Context store object with the following properties:
  {
    ContextKey: ContextKey, /* name of the store. */
    Context, /* React Context Object. */
    Provider, /* The Provider HoC. */
    use(keys), /* React Hook to use the store. returns [state, dispatch]
    - keys (optional) array of keys to return from the state.
    */
    connect(mapContextToProps, keys, options), /* The Connect HoC
    - mapContextToProps(...) function to map context [state, dispatch] to props.
    - keys (optional) array of keys to return from the state.
    - options (optional) object {useMemo = true}
    */
    getState(), /* Returns the current state of the store. */
    dispatch(action) /* Dispatch an action to your store. */
  }
  • combineReducers({...}) - Split up complex reducers into smaller chunks. Works exactly like redux implementation Redux of combineReducers().
  • combineActions({...}) - Combines actions similar to reducers and validates all your actions for uniqueness. Helps reduce the number of files you need to include in larger apps.
  • withTypeCheck(actionName or reducer, propTypes schema) - Define your action payload shape or reducers state shape by wrapping it withTypeCheck.

Middleware API

The middleware api sits between every dispatch call to your store. This allows for advanced features such as logging, analytics, crash reports, etc...

  • store.getState() - Get the current state of the store. (before the reducer has been resolved)
  • store.dispatch(action) - Dispatch a new action before (or after with async callback) the current dispatch completes.
  • next(action) - Process the next middleware in the chain. (You can modify action before passing it to the next middleware in the chain)
  • action - The passed down action.
// log every dispatch to the console
  (store) =>
    (next) =>
      (action) => {
        console.group(`Dispatching "${action.type}"`);
        console.info('Action:', action);
        console.info('Previous State:', store.getState());
        const result = next(action);
        console.info('Next State:', store.getState());
        console.groupEnd();
        return result;
      };

Example

First we need to create a context store using createContextReducer().

// ./AppStore.js
import propTypes from 'prop-types';
import { createContextReducer, reduxDevTools, withTypeCheck } from 'react-context-reducer';

// create your actions.
export const AppStoreActions = {
  Add: withTypeCheck('+')),
  Subtract: withTypeCheck('-')
};

// create your reducer.
const reducer = (state = 0, action) => {
  switch(action.types) {
    case AppStoreActions.Add:
      return state+1;
    case AppStoreActions.Subtract:
      return state-1;
    default:
      return state;
  }
};

// Create the context store and export it.
export default createContextReducer(
  "AppStore", // store name
  withTypeCheck(reducer, propTypes.number.isRequired), // reducer
  [reduxDevTools()] // middlewares
);

Now we can provide the context store to the app by wrapping it with AppStore.Provider.

// ./app.js
import React from 'react';
import AppStore from './AppStore';
import MyComponent from './MyComponent';

const App = (props) => {
  return (
    <AppStore.Provider>
      <MyComponent />
    </AppStore.Provider>
  )
};

export default App;

Connect our store to a component that needs access to state and dispatch using the AppStore.connect() HoC.

// ./MyComponent.js - AppStore.connect() HoC
import React from 'react';
import AppStore, {AppStoreActions} from './AppStore';

const MyComponent = (props) => {
  const {state, dispatch} = props;
  return (
    <div>
      <button onClick={() => dispatch({type: AppStoreActions.Add})}>Add</button>
      <button onClick={() => dispatch({type: AppStoreActions.Subtract})}>Subtract</button>
      {state}
    </div>
  )
};

export default AppStore.connect(([state, dispatch]) => ({
  // mapContextToProps
  state,
  dispatch
}))(MyComponent);

Alternatively you can use the AppStore.use(selectors) hook to also gain access to the stores state and dispatch.

// ./MyComponent.js - AppStore.use() hook
import React from 'react';
import AppStore, {AppStoreActions} from './AppStore';

const MyComponent = (props) => {
  const [state, dispatch] = AppStore.use(); // hook
  return (
    <div>
      <button onClick={() => dispatch({type: AppStoreActions.Add})}>Add</button>
      <button onClick={() => dispatch({type: AppStoreActions.Subtract})}>Subtract</button>
      {state}
    </div>
  )
};

export default MyComponent;

If everything was coded up correctly you should now see two buttons and the state value. Each time a button is pressed you will also see the action being logged to the console because of the reduxDevTools() middleware.

View Examples (Work In Progress) https://sheaivey.github.io/react-context-reducer/