Skip to content

Instantly share code, notes, and snippets.

@nemzes
Created August 16, 2018 18:06
Show Gist options
  • Save nemzes/2ba948d4af1154d687dbf9d4a8a042d7 to your computer and use it in GitHub Desktop.
Save nemzes/2ba948d4af1154d687dbf9d4a8a042d7 to your computer and use it in GitHub Desktop.
React and react-router: decouple route-based props from the match.params structure imposed by withRouter()
import React from 'react';
import { withRouter } from 'react-router';
/**
* Maps route parameters as defined in react-router and injects them as
* first-class props into a component. This avoids components being tightly
* coupled with the prop structure returned by withRouter()
*
* @example
* // Inject "family", "genus", and "species" in a URL like
* // "/f/:family/g/:genus/s/:species" as props of the same name into MyComponent
* mapRouteParamsToProps(['family', 'genus', 'species'], MyComponent);
*
* @todo Support object (key => string) as paramsToMap (rename params)
* @todo Support object (key => function) as paramsToMap (like mapStateToProps)
*
* @param {string[]} paramsToMap List of URL parameters to inject as props
* @param {React.Component} Component Component to receive props
*/
export default function mapRouteParamsToProps(paramsToMap, Component) {
return withRouter(props => {
const mappedProps = {};
paramsToMap.forEach(
param =>
(mappedProps[param] =
props.match && props.match.params
? props.match.params[param]
: undefined)
);
return React.createElement(Component, { ...mappedProps, ...props });
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment