Created
August 16, 2018 18:06
-
-
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()
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 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