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

redux-hook

v0.1.3

Published

Redux middleware to subscribe to specifically events and state tree changes

Downloads

8

Readme

redux-hook

This is a Redux middleware that allows you to subscribe to specific changes in your Redux application, and all your subscribers are passed in the action object, the new state, then the last state. The module exports a function that returns an object with middleware and decorator properties. You apply the middleware property like a normal Redux middleware, and you pass your store instance to decorator to add the functions described below.

Example

import {
  createStore,
  applyMiddleware
} from 'redux';
import createHookMiddleware from 'redux-hook';

const {
  middleware: reduxHook,
  decorator
} = createHookMiddleware();

const store = decorator(createStore((state, action) => {
  // some reducer
}, applyMiddleware(reduxHook)));

const {
  subscribeToState,
  subscribeToStateOnce,
  subscribeToKey,
  subscribeToKeyOnce,
  subscribeToEvent,
  subscribeToEventOnce
} = store;

// set up subscribers

export default store;

Function descriptions

subscribeToState

This is the core subscribe function that subscribes to any change in the state tree. The difference is that this function is passed the action object, the current state, and the last state tree, so that you don't have to keep track of references manually.

const unsubscribe = store.subscribeToState((action, currentTree, lastTree) => {
  if (lastTree.someBranch !== currentTree.someBranch) {
    store.dispatch({ type: 'SOME_EVENT' });
  }
});

subscribeToStateOnce

This function subscribes to state changes and automatically unsubscribes after it has been called once.

subscribeToKey

This function takes two arguments, the first argument can be a string representing one key in the state tree on which to listen for changes. If the first argument is a string, the second argument will be a function that will be called whenever that branch of the state tree changes, called with the last branch of the state tree by that key and the current one as arguments. If, however, the first argument to the function is an array, the second argument must be a function that will be called with the last entire state tree then the current state tree passed in as arguments.

const unsubscribe = store.subscribeToKey('someBranch', (action, currentState, lastState) => {
  // do something with changed properties
});

const otherUnsubscribe = store.subscribeToKey(['someBranch', 'someOtherBranch'], (action, currentTree, lastTree) => {
  // do something when either someBranch or someOtherBranch has changed
});

subscribeToKeyOnce

This function has the same behavior as Store#subscribeToKey but will be unsubscribed automatically after the function is called once.

subscribeToEvent

This function takes an event name as its first argument and the second argument will be a function that will be called with the action object, the current state tree, and the last state tree whenever that event is dispatched.

const unsubscribe = store.subscribeToEvent('SOME_EVENT', (action, currentTree, lastTree) => {
  // do something with state or action payload when SOME_EVENT is dispatched
});

subscribeToEventOnce

This function has the same behavior as subscribeToEvent except it is unsubscribed after the function is called once.

Motivation & Design Patterns

Manually keeping track of references to the last and current state tree in each of your subscribers can result in ugly code and can be a source of infinite recursion bugs, notably when calling dispatch from within subscribers. These subscribers handle this mechanism for you.

subscribeToEvent can be a clean way to launch actions with side-effects from a container component, while keeping your container a pure function of the redux state and dispatch function, and it also allows separation of your core application and network logic from your container. You might see a similar pattern in applications that make use of react-saga.

Example of a pure container that executes networked logic via an event subscriber:

// in SomeContainer.js

import SomeComponent from './SomeComponent';
import { connect } from 'react-redux';

export default connect(({ someBranch }) => ({ someBranch }), (dispatch) => ({
  onClick() {
    dispatch({
      type: 'REQUEST_FETCH_DATA'
    });
  }
}));

// somewhere in store.js

subscribeToEvent('REQUEST_FETCH_DATA', () => {
  fetchDataAsync((err, result) => {
    dispatch({
      type: 'DATA_FETCH_COMPLETE',
      payload: result
    });
  });
});

Author

Raymond Pulver IV

License

MIT