tappleby / redux-batched-subscribe

store enhancer for https://github.com/reactjs/redux which allows batching subscribe notifications.
MIT License
504 stars 32 forks source link

Update readme to provide a simple example of how to dispatch multiple actions without notifying subscribers until all complete (without react or or other dependencies) #11

Open thinkloop opened 8 years ago

thinkloop commented 8 years ago

It seems like this might be what I'm looking for, but can't fully understand it with the advanced/indirect examples.

peteruithoven commented 7 years ago

We for example batch using request animation frame and React's batchedUpdates. Below is a simple example using just request animation frame. This means that when mouse / touch events trigger actions (which are triggered more often than animation frames), you can make sure the subscribed (connected / smart) components only get notified every animation frame (and only when there where actions called of course).

import raf from 'raf';
import { createStore } from 'redux';
import { batchedSubscribe } from 'redux-batched-subscribe';

let rafID;
function rafUpdateBatcher(notify) {
  if (rafID) return; // prevent multiple request animation frame callbacks
  rafID = raf(() => {
    rafID = null;
    notify();
  });
}

// Note: passing batchedSubscribe as the last argument to createStore requires redux@>=3.1.0
const store = createStore(reducer, intialState, batchedSubscribe(rafUpdateBatcher));
woshi82 commented 7 years ago

@peteruithoven can you show the Complete example,i still cannot understand what the notify mean? thank you very much. :)

woshi82 commented 7 years ago

oh~ it seem like control the subscription asynchronously

peteruithoven commented 7 years ago

Testing my PR (https://github.com/tappleby/redux-batched-subscribe/pull/17) I created the following simple example, would that clarify things?

import { createStore, compose, applyMiddleware } from 'redux';
import raf from 'raf';
import { batchedSubscribe } from 'redux-batched-subscribe';

// Actions
export const ADD = 'ADD';
export function add(text) {
  return { type: ADD, text };
}

// Reducers
const initialState = [];
function reducer(state = initialState, action) {
  console.log('reduce: ', action.type);
  switch(action.type) {
    case ADD:
      return [...state, action.text];
    default:
      return state;
  }
}

// Batcher
let rafID;
export default function rafUpdateBatcher(notify, action, getState) {
  if (rafID) return;
  rafID = raf(() => {
    rafID = null;
    notify();
  });
}

// Store
const store = createStore(
  reducer,
  initialState,
  // disable this line to see difference
  batchedSubscribe(rafUpdateBatcher)
);

// Experiment
store.subscribe(function() {
  const state = store.getState();
  console.log('notified: ', state);
});

store.dispatch(add('a'));
store.dispatch(add('b'));
store.dispatch(add('c'));
tappleby commented 7 years ago

This RAF example looks handy but feels like more of an advanced implementation. I think it would be hard to follow in a readme.

debouncing is a fairly common pattern for throttling how often a function gets called. Perhaps more of a description here would help out?

paynecodes commented 6 years ago

@tappleby I think @peteruithoven's example code is one of the more compelling use cases I've seen for this lib. I believe it should be noted in the docs even if it's just a link to it. In any case, thanks for this lib! 👍