Created
September 12, 2018 05:34
-
-
Save riquito/4befa64c500464b44cd7e4364dd2a840 to your computer and use it in GitHub Desktop.
Create an higher order component that receives props from a context consumer.
This file contains 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
/** | |
* Create an higher order component that receives props from a context consumer. | |
* | |
* // e.g. Create your with<SomeConsumer> function | |
* // const withDispatch = makeWithConsumer(DispatchContext.consumer, 'Dispatch') | |
* | |
* // e.g. pass the consumer props as they are | |
* const ButtonConnected = withDispatch(Button) | |
* | |
* // e.g. transform the props using an object as map | |
* // (unmapped props are passed with the original keys) | |
* const ButtonConnected = withDispatch(Button, { dispatch: onClick }) | |
* | |
* // e.g. transform the consumer props | |
* const ButtonConnected = withDispatch(Button, | |
* (({ dispatch }) => ({ | |
* onSubmit: value => dispatch(doSomething(value)), | |
* })) | |
* ) | |
* | |
* @param {class} Consumer React context consumer | |
* @param {string} consumerName name, for debugging purposes | |
* @return {function} the HOC | |
*/ | |
export function makeWithConsumer(Consumer, consumerName = 'Consumer') { | |
function withConsumer(Comp, mapKeysToX = null) { | |
function ComponentWithConsumer(props) { | |
return ( | |
<Consumer> | |
{consumerProps => ( | |
<Comp {...props} {...keysRemapper(consumerProps, mapKeysToX)} /> | |
)} | |
</Consumer> | |
) | |
} | |
ComponentWithConsumer.displayName = `ComponentWith${consumerName}` | |
return ComponentWithConsumer | |
} | |
withConsumer.displayName = `with${consumerName}` | |
return withConsumer | |
} | |
/** | |
* Transform the keys of an object. | |
* | |
* @param {object} obj the object whose key we want to change | |
* @param {mapKeysToX} one of | |
* - an object that maps oldKey: newKey (missing keys are left untouched) | |
* - a function that gets an object and return a new object | |
* - null (obj is returned) | |
*/ | |
function keysRemapper(obj, mapKeysToX = null) { | |
if (!mapKeysToX) { | |
return obj | |
} else if (typeof mapKeysToX === 'function') { | |
return mapKeysToX(obj) | |
} else { | |
const newObj = { | |
...obj, | |
} | |
for (const [oldKey, newKey] of Object.entries(mapKeysToX)) { | |
delete newObj[oldKey] | |
newObj[newKey] = obj[oldKey] | |
} | |
return newObj | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment