0.1.3 • Published 7 years ago

redux-hook v0.1.3

Weekly downloads
1
License
MIT
Repository
bitbucket
Last release
7 years ago

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

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago