@vve/react-router
Version:
react router for react-helper & with keep-alive
92 lines (90 loc) • 3.69 kB
JavaScript
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