UNPKG

@vve/react-router

Version:

react router for react-helper & with keep-alive

92 lines (90 loc) 3.69 kB
import _objectSpread from "@babel/runtime/helpers/objectSpread2"; /* eslint-disable func-names */ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import invariant from 'tiny-invariant'; import warning from 'tiny-warning'; import { parse } from 'qs'; import RouterContext from "./router-context"; import matchPath from "./match-path"; import DeactivatableWrapper from "./deactivatable-wrapper"; function decorateMatch(match, search) { if (!match || !search) return match; return _objectSpread(_objectSpread({}, match), {}, { url: `${match.url}${search}`, query: parse(search.slice(1)) }); } class Switch extends React.Component { constructor(props) { super(props); this.retainRoutes = new Map(); } render() { var _this$props = this.props, givenLocation = _this$props.location, children = _this$props.children; return /*#__PURE__*/React.createElement(RouterContext.Consumer, null, context => { invariant(context, 'You should not use <Switch> outside a <Router>'); var location = givenLocation || context.location; var element; var match; // We use React.Children.forEach instead of React.Children.toArray().find() // here because toArray adds keys to all child elements and we do not want // to trigger an unmount/remount for two <Route>s that render the same // component at different URLs. React.Children.forEach(children, child => { if (match == null && /*#__PURE__*/React.isValidElement(child)) { element = child; // @TODO what does 'from' mean? var path = child.props.path || child.props.from; match = path ? decorateMatch(matchPath(location.pathname, _objectSpread(_objectSpread({}, child.props), {}, { path })), location.search) : context.match; if (child.props.keepAlive) { this.retainRoutes.set(path, child); } } }); var matchedRetain = false; var routes = Array.from(this.retainRoutes.values()).map(ele => { var active = ele.props.path === element.props.path; var props = { rrcActive: active }; if (active) { matchedRetain = true; props.location = location; props.computedMatch = match; } return /*#__PURE__*/React.createElement(DeactivatableWrapper, { key: ele.props.path, active: active }, /*#__PURE__*/React.cloneElement(ele, props)); }); if (!matchedRetain && match) { routes.push( /*#__PURE__*/React.createElement(DeactivatableWrapper, { key: element.props.path || 'defaultRoute....', active: true }, /*#__PURE__*/React.cloneElement(element, { location, computedMatch: match, rrcActive: true }))); } return /*#__PURE__*/React.createElement(Fragment, null, routes); }); } } if (process.env.NODE_ENV !== 'production') { Switch.propTypes = { children: PropTypes.node, location: PropTypes.object }; Switch.prototype.componentDidUpdate = function (prevProps) { warning(!(this.props.location && !prevProps.location), '<Switch> elements should not change from uncontrolled to controlled (or vice versa). You initially used no "location" prop and then provided one on a subsequent render.'); warning(!(!this.props.location && prevProps.location), '<Switch> elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.'); }; } export default Switch; //# sourceMappingURL=switch.js.map