Last active
March 31, 2018 23:37
-
-
Save artalar/56394d7e2dbfc4f45aa01a7ed01778a7 to your computer and use it in GitHub Desktop.
contextFactory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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