src/modules/withRoute.js
/**
 * It creates and returns a new wrapper ComponentWithRoute around BaseComponent
 *
 * @param BaseComponent - the component to be wrapped
 * @param storeName - the mobx-router5 store instance name. Default 'routerStore'
 * @returns {ComponentWithRoute}
 */
It creates and returns a new wrapper ComponentWithRoute around BaseComponent
@param BaseComponent - the component to be wrapped
@param storeName - the mobx-router5 store instance name. Default 'routerStore'
@returns {ComponentWithRoute}
It creates and returns a new wrapper ComponentWithRoute around BaseComponent @param BaseComponent - the component to be wrapped @param storeName - the mobx - router5 store instance name . Default ' routerStore ' @returns { ComponentWithRoute }
function withRoute(BaseComponent, storeName = 'routerStore') {
  @inject(storeName)
  @observer
  class ComponentWithRoute extends Component {
    static computeClassName(className, activeClassName, isActive) {
      return (className ? className.split(' ') : [])
      .concat(isActive ? [activeClassName] : []).join(' ');
    }
    constructor(props) {
      super(props);
      this.isActive = this.isActive.bind(this); 
      this.routerStore = props[storeName];
      ifNot(
        this.routerStore,
        '[react-mobx-router5][withRoute] missing routerStore'
      );
      this.router = this.routerStore.router || null;
      ifNot(
        this.router && this.router.hasPlugin('MOBX_PLUGIN'),
        '[react-mobx-router5][withRoute] missing mobx plugin'
      );
    }
    isActive(routeName, routeParams, activeStrict) {
      return this.router.isActive(routeName, routeParams, activeStrict);
    }
    render() {
      ifNot(
        !this.props.route,
        '[react-mobx-router5][withRoute] prop names `route` is reserved.'
      );
      const {activeStrict, activeClassName, ...passThroughProps} = this.props;
      const {routeName, routeParams, className } = passThroughProps;
      let currentClassName = className;
      let isActive = null;
      if (routeName) {
        isActive = this.isActive(routeName, routeParams, activeStrict);
        currentClassName = ComponentWithRoute.computeClassName(className, activeClassName, isActive);
      }
      const {route} = this.routerStore;
      const newProps = {
        ...passThroughProps,
        isActive,
        className: currentClassName,
        routerStore: this.routerStore,
        route
      };
      return (
        <BaseComponent {...newProps} >
          {passThroughProps.children}
        </BaseComponent>
      );
    }
  }
  ComponentWithRoute.displayName = 'WithRoute[' + getDisplayName(BaseComponent) + ']';
  ComponentWithRoute.defaultProps = {
    className: '',
    routeParams: {},
    activeClassName: 'active',
    activeStrict: false
  };
  ComponentWithRoute.propTypes = {
    className: PropTypes.string,
    activeClassName: PropTypes.string,
    activeStrict: PropTypes.bool,
    routeParams: PropTypes.object,
    routeName: PropTypes.string,
    children: PropTypes.node
  };
  ComponentWithRoute.wrappedComponent.propTypes  = {
    [storeName]: PropTypes.object.isRequired
  };
  return ComponentWithRoute;
}
function withRoute ( BaseComponent , storeName = 'routerStore' ) { @ inject ( storeName ) @ observer class ComponentWithRoute extends Component { static computeClassName ( className , activeClassName , isActive ) { return ( className ? className . split ( ' ' ) : [ ] ) . concat ( isActive ? [ activeClassName ] : [ ] ) . join ( ' ' ) ; } constructor ( props ) { super ( props ) ; this . isActive = this . isActive . bind ( this ) ; this . routerStore = props [ storeName ] ; ifNot ( this . routerStore , '[react-mobx-router5][withRoute] missing routerStore' ) ; this . router = this . routerStore . router || null ; ifNot ( this . router && this . router . hasPlugin ( 'MOBX_PLUGIN' ) , '[react-mobx-router5][withRoute] missing mobx plugin' ) ; } isActive ( routeName , routeParams , activeStrict ) { return this . router . isActive ( routeName , routeParams , activeStrict ) ; } render ( ) { ifNot ( ! this . props . route , '[react-mobx-router5][withRoute] prop names `route` is reserved.' ) ; const { activeStrict , activeClassName , ... passThroughProps } = this . props ; const { routeName , routeParams , className } = passThroughProps ; let currentClassName = className ; let isActive = null ; if ( routeName ) { isActive = this . isActive ( routeName , routeParams , activeStrict ) ; currentClassName = ComponentWithRoute . computeClassName ( className , activeClassName , isActive ) ; } const { route } = this . routerStore ; const newProps = { ... passThroughProps , isActive , className : currentClassName , routerStore : this . routerStore , route } ; return ( < BaseComponent { ... newProps } > { passThroughProps . children } < / BaseComponent > ) ; } } ComponentWithRoute . displayName = 'WithRoute[' + getDisplayName ( BaseComponent ) + ']' ; ComponentWithRoute . defaultProps = { className : '' , routeParams : { } , activeClassName : 'active' , activeStrict : false } ; ComponentWithRoute . propTypes = { className : PropTypes . string , activeClassName : PropTypes . string , activeStrict : PropTypes . bool , routeParams : PropTypes . object , routeName : PropTypes . string , children : PropTypes . node } ; ComponentWithRoute . wrappedComponent . propTypes = { [ storeName ] : PropTypes . object . isRequired } ; return ComponentWithRoute ; }
It creates and returns a new wrapper ComponentWithRoute around BaseComponent
 @param BaseComponent - the component to be wrapped
 @param storeName - the mobx-router5 store instance name.
It creates and returns a new wrapper ComponentWithRoute around BaseComponent @param BaseComponent - the component to be wrapped @param storeName - the mobx - router5 store instance name .
/**
   * HOC Wrapper ComponentWithRoute around the BaseComponent
   *
   * The wrapper is injected with the mobx routerStore and decorated with @observer
   * Note: @inject will also create another wrapper around the ComponentWithRoute
   *
   * The component accepts any props and forward them to the wrapped component.
   * Any route changes will trigger a rendering of ComponentWithRoute.
   *
   * Also the wrapped BaseComponent (and children) will re-render because it's injected with:
   *   - route: the mobx observable routerStore.route, used to trigger a re-rendering of the BaseComponent when the route changes
   *   - className: if a prop `routeName` is passed to ComponentWithRoute then it adds an `active` className
   *     to the original className when routeName==routerStore.route
   *   - isActive: boolean, computed and injected when `routeName` is passed
   *
   * Some special props passed are used to compute if the current wrapped element should be considered "active" or not:
   *  - `routeName` (string): name of the route associated with the component
   *  - `routeParams` (obj) **default** `{}`: the route params
   *  - `activeStrict` (bool) **default** `false`: whether to check if `routeName` is the active route, or part of the active route
   */ // Bindings // Don't forward these // De-referencing a mobx-observable will trigger a re-rendering (because of the @observer) // Forwarded // These won't be forwarded // Defaults // Optional // Because @inject creates an extra HOC /* remove-proptypes */