Skip to content

Instantly share code, notes, and snippets.

@artalar
Last active March 31, 2018 23:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save artalar/56394d7e2dbfc4f45aa01a7ed01778a7 to your computer and use it in GitHub Desktop.
Save artalar/56394d7e2dbfc4f45aa01a7ed01778a7 to your computer and use it in GitHub Desktop.
contextFactory
import * as React from 'react';
import { createSubscription } from 'create-subscription';
const shallowCompare = (newObj, oldObj) => {
const newObjKeys = Object.keys(newObj);
const oldObjKeys = Object.keys(oldObj);
return (
newObjKeys.length === oldObjKeys.length && newObjKeys.every(key => newObj[key] === oldObj[key])
);
};
export const contextFactory = (store, actions) => {
const { Provider: ProviderBase, Consumer } = React.createContext(store.state);
const Subscription = createSubscription({
getCurrentValue: ({ state }) => {
return { actions, state };
},
subscribe: (store, callback) => {
store.subscribe(state => callback({ actions, state }));
return () => store.unsubscribe(callback);
},
});
const Provider = ({ children }) => (
<Subscription source={store}>
{value => <ProviderBase value={value}>{children}</ProviderBase>}
</Subscription>
);
const connect = selector => target => ({ children, ...props }) => {
let updateFromParent = true;
let cachedState = null;
let cacheComponent = null;
return (
<Consumer>
{value => {
const state = selector(value, props);
if (!updateFromParent && (state === cachedState || shallowCompare(state, cachedState))) {
updateFromParent = false;
return cacheComponent;
} else {
updateFromParent = false;
cachedState = state;
return (cacheComponent = React.createElement(target, { ...props, ...state }, children));
}
}}
</Consumer>
);
};
return {
connect,
Provider,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment