react-router.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. import _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';
  2. import React from 'react';
  3. import PropTypes from 'prop-types';
  4. import { createMemoryHistory, createLocation, locationsAreEqual, createPath } from 'history';
  5. import warning from 'tiny-warning';
  6. import createContext from 'mini-create-react-context';
  7. import invariant from 'tiny-invariant';
  8. import _extends from '@babel/runtime/helpers/esm/extends';
  9. import pathToRegexp from 'path-to-regexp';
  10. import { isValidElementType } from 'react-is';
  11. import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose';
  12. import hoistStatics from 'hoist-non-react-statics';
  13. // TODO: Replace with React.createContext once we can assume React 16+
  14. var createNamedContext = function createNamedContext(name) {
  15. var context = createContext();
  16. context.displayName = name;
  17. return context;
  18. };
  19. var historyContext =
  20. /*#__PURE__*/
  21. createNamedContext("Router-History");
  22. // TODO: Replace with React.createContext once we can assume React 16+
  23. var createNamedContext$1 = function createNamedContext(name) {
  24. var context = createContext();
  25. context.displayName = name;
  26. return context;
  27. };
  28. var context =
  29. /*#__PURE__*/
  30. createNamedContext$1("Router");
  31. /**
  32. * The public API for putting history on context.
  33. */
  34. var Router =
  35. /*#__PURE__*/
  36. function (_React$Component) {
  37. _inheritsLoose(Router, _React$Component);
  38. Router.computeRootMatch = function computeRootMatch(pathname) {
  39. return {
  40. path: "/",
  41. url: "/",
  42. params: {},
  43. isExact: pathname === "/"
  44. };
  45. };
  46. function Router(props) {
  47. var _this;
  48. _this = _React$Component.call(this, props) || this;
  49. _this.state = {
  50. location: props.history.location
  51. }; // This is a bit of a hack. We have to start listening for location
  52. // changes here in the constructor in case there are any <Redirect>s
  53. // on the initial render. If there are, they will replace/push when
  54. // they mount and since cDM fires in children before parents, we may
  55. // get a new location before the <Router> is mounted.
  56. _this._isMounted = false;
  57. _this._pendingLocation = null;
  58. if (!props.staticContext) {
  59. _this.unlisten = props.history.listen(function (location) {
  60. if (_this._isMounted) {
  61. _this.setState({
  62. location: location
  63. });
  64. } else {
  65. _this._pendingLocation = location;
  66. }
  67. });
  68. }
  69. return _this;
  70. }
  71. var _proto = Router.prototype;
  72. _proto.componentDidMount = function componentDidMount() {
  73. this._isMounted = true;
  74. if (this._pendingLocation) {
  75. this.setState({
  76. location: this._pendingLocation
  77. });
  78. }
  79. };
  80. _proto.componentWillUnmount = function componentWillUnmount() {
  81. if (this.unlisten) this.unlisten();
  82. };
  83. _proto.render = function render() {
  84. return React.createElement(context.Provider, {
  85. value: {
  86. history: this.props.history,
  87. location: this.state.location,
  88. match: Router.computeRootMatch(this.state.location.pathname),
  89. staticContext: this.props.staticContext
  90. }
  91. }, React.createElement(historyContext.Provider, {
  92. children: this.props.children || null,
  93. value: this.props.history
  94. }));
  95. };
  96. return Router;
  97. }(React.Component);
  98. if (process.env.NODE_ENV !== "production") {
  99. Router.propTypes = {
  100. children: PropTypes.node,
  101. history: PropTypes.object.isRequired,
  102. staticContext: PropTypes.object
  103. };
  104. Router.prototype.componentDidUpdate = function (prevProps) {
  105. process.env.NODE_ENV !== "production" ? warning(prevProps.history === this.props.history, "You cannot change <Router history>") : void 0;
  106. };
  107. }
  108. /**
  109. * The public API for a <Router> that stores location in memory.
  110. */
  111. var MemoryRouter =
  112. /*#__PURE__*/
  113. function (_React$Component) {
  114. _inheritsLoose(MemoryRouter, _React$Component);
  115. function MemoryRouter() {
  116. var _this;
  117. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  118. args[_key] = arguments[_key];
  119. }
  120. _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
  121. _this.history = createMemoryHistory(_this.props);
  122. return _this;
  123. }
  124. var _proto = MemoryRouter.prototype;
  125. _proto.render = function render() {
  126. return React.createElement(Router, {
  127. history: this.history,
  128. children: this.props.children
  129. });
  130. };
  131. return MemoryRouter;
  132. }(React.Component);
  133. if (process.env.NODE_ENV !== "production") {
  134. MemoryRouter.propTypes = {
  135. initialEntries: PropTypes.array,
  136. initialIndex: PropTypes.number,
  137. getUserConfirmation: PropTypes.func,
  138. keyLength: PropTypes.number,
  139. children: PropTypes.node
  140. };
  141. MemoryRouter.prototype.componentDidMount = function () {
  142. process.env.NODE_ENV !== "production" ? warning(!this.props.history, "<MemoryRouter> ignores the history prop. To use a custom history, " + "use `import { Router }` instead of `import { MemoryRouter as Router }`.") : void 0;
  143. };
  144. }
  145. var Lifecycle =
  146. /*#__PURE__*/
  147. function (_React$Component) {
  148. _inheritsLoose(Lifecycle, _React$Component);
  149. function Lifecycle() {
  150. return _React$Component.apply(this, arguments) || this;
  151. }
  152. var _proto = Lifecycle.prototype;
  153. _proto.componentDidMount = function componentDidMount() {
  154. if (this.props.onMount) this.props.onMount.call(this, this);
  155. };
  156. _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
  157. if (this.props.onUpdate) this.props.onUpdate.call(this, this, prevProps);
  158. };
  159. _proto.componentWillUnmount = function componentWillUnmount() {
  160. if (this.props.onUnmount) this.props.onUnmount.call(this, this);
  161. };
  162. _proto.render = function render() {
  163. return null;
  164. };
  165. return Lifecycle;
  166. }(React.Component);
  167. /**
  168. * The public API for prompting the user before navigating away from a screen.
  169. */
  170. function Prompt(_ref) {
  171. var message = _ref.message,
  172. _ref$when = _ref.when,
  173. when = _ref$when === void 0 ? true : _ref$when;
  174. return React.createElement(context.Consumer, null, function (context) {
  175. !context ? process.env.NODE_ENV !== "production" ? invariant(false, "You should not use <Prompt> outside a <Router>") : invariant(false) : void 0;
  176. if (!when || context.staticContext) return null;
  177. var method = context.history.block;
  178. return React.createElement(Lifecycle, {
  179. onMount: function onMount(self) {
  180. self.release = method(message);
  181. },
  182. onUpdate: function onUpdate(self, prevProps) {
  183. if (prevProps.message !== message) {
  184. self.release();
  185. self.release = method(message);
  186. }
  187. },
  188. onUnmount: function onUnmount(self) {
  189. self.release();
  190. },
  191. message: message
  192. });
  193. });
  194. }
  195. if (process.env.NODE_ENV !== "production") {
  196. var messageType = PropTypes.oneOfType([PropTypes.func, PropTypes.string]);
  197. Prompt.propTypes = {
  198. when: PropTypes.bool,
  199. message: messageType.isRequired
  200. };
  201. }
  202. var cache = {};
  203. var cacheLimit = 10000;
  204. var cacheCount = 0;
  205. function compilePath(path) {
  206. if (cache[path]) return cache[path];
  207. var generator = pathToRegexp.compile(path);
  208. if (cacheCount < cacheLimit) {
  209. cache[path] = generator;
  210. cacheCount++;
  211. }
  212. return generator;
  213. }
  214. /**
  215. * Public API for generating a URL pathname from a path and parameters.
  216. */
  217. function generatePath(path, params) {
  218. if (path === void 0) {
  219. path = "/";
  220. }
  221. if (params === void 0) {
  222. params = {};
  223. }
  224. return path === "/" ? path : compilePath(path)(params, {
  225. pretty: true
  226. });
  227. }
  228. /**
  229. * The public API for navigating programmatically with a component.
  230. */
  231. function Redirect(_ref) {
  232. var computedMatch = _ref.computedMatch,
  233. to = _ref.to,
  234. _ref$push = _ref.push,
  235. push = _ref$push === void 0 ? false : _ref$push;
  236. return React.createElement(context.Consumer, null, function (context) {
  237. !context ? process.env.NODE_ENV !== "production" ? invariant(false, "You should not use <Redirect> outside a <Router>") : invariant(false) : void 0;
  238. var history = context.history,
  239. staticContext = context.staticContext;
  240. var method = push ? history.push : history.replace;
  241. var location = createLocation(computedMatch ? typeof to === "string" ? generatePath(to, computedMatch.params) : _extends({}, to, {
  242. pathname: generatePath(to.pathname, computedMatch.params)
  243. }) : to); // When rendering in a static context,
  244. // set the new location immediately.
  245. if (staticContext) {
  246. method(location);
  247. return null;
  248. }
  249. return React.createElement(Lifecycle, {
  250. onMount: function onMount() {
  251. method(location);
  252. },
  253. onUpdate: function onUpdate(self, prevProps) {
  254. var prevLocation = createLocation(prevProps.to);
  255. if (!locationsAreEqual(prevLocation, _extends({}, location, {
  256. key: prevLocation.key
  257. }))) {
  258. method(location);
  259. }
  260. },
  261. to: to
  262. });
  263. });
  264. }
  265. if (process.env.NODE_ENV !== "production") {
  266. Redirect.propTypes = {
  267. push: PropTypes.bool,
  268. from: PropTypes.string,
  269. to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired
  270. };
  271. }
  272. var cache$1 = {};
  273. var cacheLimit$1 = 10000;
  274. var cacheCount$1 = 0;
  275. function compilePath$1(path, options) {
  276. var cacheKey = "" + options.end + options.strict + options.sensitive;
  277. var pathCache = cache$1[cacheKey] || (cache$1[cacheKey] = {});
  278. if (pathCache[path]) return pathCache[path];
  279. var keys = [];
  280. var regexp = pathToRegexp(path, keys, options);
  281. var result = {
  282. regexp: regexp,
  283. keys: keys
  284. };
  285. if (cacheCount$1 < cacheLimit$1) {
  286. pathCache[path] = result;
  287. cacheCount$1++;
  288. }
  289. return result;
  290. }
  291. /**
  292. * Public API for matching a URL pathname to a path.
  293. */
  294. function matchPath(pathname, options) {
  295. if (options === void 0) {
  296. options = {};
  297. }
  298. if (typeof options === "string" || Array.isArray(options)) {
  299. options = {
  300. path: options
  301. };
  302. }
  303. var _options = options,
  304. path = _options.path,
  305. _options$exact = _options.exact,
  306. exact = _options$exact === void 0 ? false : _options$exact,
  307. _options$strict = _options.strict,
  308. strict = _options$strict === void 0 ? false : _options$strict,
  309. _options$sensitive = _options.sensitive,
  310. sensitive = _options$sensitive === void 0 ? false : _options$sensitive;
  311. var paths = [].concat(path);
  312. return paths.reduce(function (matched, path) {
  313. if (!path && path !== "") return null;
  314. if (matched) return matched;
  315. var _compilePath = compilePath$1(path, {
  316. end: exact,
  317. strict: strict,
  318. sensitive: sensitive
  319. }),
  320. regexp = _compilePath.regexp,
  321. keys = _compilePath.keys;
  322. var match = regexp.exec(pathname);
  323. if (!match) return null;
  324. var url = match[0],
  325. values = match.slice(1);
  326. var isExact = pathname === url;
  327. if (exact && !isExact) return null;
  328. return {
  329. path: path,
  330. // the path used to match
  331. url: path === "/" && url === "" ? "/" : url,
  332. // the matched portion of the URL
  333. isExact: isExact,
  334. // whether or not we matched exactly
  335. params: keys.reduce(function (memo, key, index) {
  336. memo[key.name] = values[index];
  337. return memo;
  338. }, {})
  339. };
  340. }, null);
  341. }
  342. function isEmptyChildren(children) {
  343. return React.Children.count(children) === 0;
  344. }
  345. function evalChildrenDev(children, props, path) {
  346. var value = children(props);
  347. process.env.NODE_ENV !== "production" ? warning(value !== undefined, "You returned `undefined` from the `children` function of " + ("<Route" + (path ? " path=\"" + path + "\"" : "") + ">, but you ") + "should have returned a React element or `null`") : void 0;
  348. return value || null;
  349. }
  350. /**
  351. * The public API for matching a single path and rendering.
  352. */
  353. var Route =
  354. /*#__PURE__*/
  355. function (_React$Component) {
  356. _inheritsLoose(Route, _React$Component);
  357. function Route() {
  358. return _React$Component.apply(this, arguments) || this;
  359. }
  360. var _proto = Route.prototype;
  361. _proto.render = function render() {
  362. var _this = this;
  363. return React.createElement(context.Consumer, null, function (context$1) {
  364. !context$1 ? process.env.NODE_ENV !== "production" ? invariant(false, "You should not use <Route> outside a <Router>") : invariant(false) : void 0;
  365. var location = _this.props.location || context$1.location;
  366. var match = _this.props.computedMatch ? _this.props.computedMatch // <Switch> already computed the match for us
  367. : _this.props.path ? matchPath(location.pathname, _this.props) : context$1.match;
  368. var props = _extends({}, context$1, {
  369. location: location,
  370. match: match
  371. });
  372. var _this$props = _this.props,
  373. children = _this$props.children,
  374. component = _this$props.component,
  375. render = _this$props.render; // Preact uses an empty array as children by
  376. // default, so use null if that's the case.
  377. if (Array.isArray(children) && children.length === 0) {
  378. children = null;
  379. }
  380. return React.createElement(context.Provider, {
  381. value: props
  382. }, props.match ? children ? typeof children === "function" ? process.env.NODE_ENV !== "production" ? evalChildrenDev(children, props, _this.props.path) : children(props) : children : component ? React.createElement(component, props) : render ? render(props) : null : typeof children === "function" ? process.env.NODE_ENV !== "production" ? evalChildrenDev(children, props, _this.props.path) : children(props) : null);
  383. });
  384. };
  385. return Route;
  386. }(React.Component);
  387. if (process.env.NODE_ENV !== "production") {
  388. Route.propTypes = {
  389. children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
  390. component: function component(props, propName) {
  391. if (props[propName] && !isValidElementType(props[propName])) {
  392. return new Error("Invalid prop 'component' supplied to 'Route': the prop is not a valid React component");
  393. }
  394. },
  395. exact: PropTypes.bool,
  396. location: PropTypes.object,
  397. path: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
  398. render: PropTypes.func,
  399. sensitive: PropTypes.bool,
  400. strict: PropTypes.bool
  401. };
  402. Route.prototype.componentDidMount = function () {
  403. process.env.NODE_ENV !== "production" ? warning(!(this.props.children && !isEmptyChildren(this.props.children) && this.props.component), "You should not use <Route component> and <Route children> in the same route; <Route component> will be ignored") : void 0;
  404. process.env.NODE_ENV !== "production" ? warning(!(this.props.children && !isEmptyChildren(this.props.children) && this.props.render), "You should not use <Route render> and <Route children> in the same route; <Route render> will be ignored") : void 0;
  405. process.env.NODE_ENV !== "production" ? warning(!(this.props.component && this.props.render), "You should not use <Route component> and <Route render> in the same route; <Route render> will be ignored") : void 0;
  406. };
  407. Route.prototype.componentDidUpdate = function (prevProps) {
  408. process.env.NODE_ENV !== "production" ? warning(!(this.props.location && !prevProps.location), '<Route> 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.') : void 0;
  409. process.env.NODE_ENV !== "production" ? warning(!(!this.props.location && prevProps.location), '<Route> elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.') : void 0;
  410. };
  411. }
  412. function addLeadingSlash(path) {
  413. return path.charAt(0) === "/" ? path : "/" + path;
  414. }
  415. function addBasename(basename, location) {
  416. if (!basename) return location;
  417. return _extends({}, location, {
  418. pathname: addLeadingSlash(basename) + location.pathname
  419. });
  420. }
  421. function stripBasename(basename, location) {
  422. if (!basename) return location;
  423. var base = addLeadingSlash(basename);
  424. if (location.pathname.indexOf(base) !== 0) return location;
  425. return _extends({}, location, {
  426. pathname: location.pathname.substr(base.length)
  427. });
  428. }
  429. function createURL(location) {
  430. return typeof location === "string" ? location : createPath(location);
  431. }
  432. function staticHandler(methodName) {
  433. return function () {
  434. process.env.NODE_ENV !== "production" ? invariant(false, "You cannot %s with <StaticRouter>", methodName) : invariant(false) ;
  435. };
  436. }
  437. function noop() {}
  438. /**
  439. * The public top-level API for a "static" <Router>, so-called because it
  440. * can't actually change the current location. Instead, it just records
  441. * location changes in a context object. Useful mainly in testing and
  442. * server-rendering scenarios.
  443. */
  444. var StaticRouter =
  445. /*#__PURE__*/
  446. function (_React$Component) {
  447. _inheritsLoose(StaticRouter, _React$Component);
  448. function StaticRouter() {
  449. var _this;
  450. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  451. args[_key] = arguments[_key];
  452. }
  453. _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
  454. _this.handlePush = function (location) {
  455. return _this.navigateTo(location, "PUSH");
  456. };
  457. _this.handleReplace = function (location) {
  458. return _this.navigateTo(location, "REPLACE");
  459. };
  460. _this.handleListen = function () {
  461. return noop;
  462. };
  463. _this.handleBlock = function () {
  464. return noop;
  465. };
  466. return _this;
  467. }
  468. var _proto = StaticRouter.prototype;
  469. _proto.navigateTo = function navigateTo(location, action) {
  470. var _this$props = this.props,
  471. _this$props$basename = _this$props.basename,
  472. basename = _this$props$basename === void 0 ? "" : _this$props$basename,
  473. _this$props$context = _this$props.context,
  474. context = _this$props$context === void 0 ? {} : _this$props$context;
  475. context.action = action;
  476. context.location = addBasename(basename, createLocation(location));
  477. context.url = createURL(context.location);
  478. };
  479. _proto.render = function render() {
  480. var _this$props2 = this.props,
  481. _this$props2$basename = _this$props2.basename,
  482. basename = _this$props2$basename === void 0 ? "" : _this$props2$basename,
  483. _this$props2$context = _this$props2.context,
  484. context = _this$props2$context === void 0 ? {} : _this$props2$context,
  485. _this$props2$location = _this$props2.location,
  486. location = _this$props2$location === void 0 ? "/" : _this$props2$location,
  487. rest = _objectWithoutPropertiesLoose(_this$props2, ["basename", "context", "location"]);
  488. var history = {
  489. createHref: function createHref(path) {
  490. return addLeadingSlash(basename + createURL(path));
  491. },
  492. action: "POP",
  493. location: stripBasename(basename, createLocation(location)),
  494. push: this.handlePush,
  495. replace: this.handleReplace,
  496. go: staticHandler("go"),
  497. goBack: staticHandler("goBack"),
  498. goForward: staticHandler("goForward"),
  499. listen: this.handleListen,
  500. block: this.handleBlock
  501. };
  502. return React.createElement(Router, _extends({}, rest, {
  503. history: history,
  504. staticContext: context
  505. }));
  506. };
  507. return StaticRouter;
  508. }(React.Component);
  509. if (process.env.NODE_ENV !== "production") {
  510. StaticRouter.propTypes = {
  511. basename: PropTypes.string,
  512. context: PropTypes.object,
  513. location: PropTypes.oneOfType([PropTypes.string, PropTypes.object])
  514. };
  515. StaticRouter.prototype.componentDidMount = function () {
  516. process.env.NODE_ENV !== "production" ? warning(!this.props.history, "<StaticRouter> ignores the history prop. To use a custom history, " + "use `import { Router }` instead of `import { StaticRouter as Router }`.") : void 0;
  517. };
  518. }
  519. /**
  520. * The public API for rendering the first <Route> that matches.
  521. */
  522. var Switch =
  523. /*#__PURE__*/
  524. function (_React$Component) {
  525. _inheritsLoose(Switch, _React$Component);
  526. function Switch() {
  527. return _React$Component.apply(this, arguments) || this;
  528. }
  529. var _proto = Switch.prototype;
  530. _proto.render = function render() {
  531. var _this = this;
  532. return React.createElement(context.Consumer, null, function (context) {
  533. !context ? process.env.NODE_ENV !== "production" ? invariant(false, "You should not use <Switch> outside a <Router>") : invariant(false) : void 0;
  534. var location = _this.props.location || context.location;
  535. var element, match; // We use React.Children.forEach instead of React.Children.toArray().find()
  536. // here because toArray adds keys to all child elements and we do not want
  537. // to trigger an unmount/remount for two <Route>s that render the same
  538. // component at different URLs.
  539. React.Children.forEach(_this.props.children, function (child) {
  540. if (match == null && React.isValidElement(child)) {
  541. element = child;
  542. var path = child.props.path || child.props.from;
  543. match = path ? matchPath(location.pathname, _extends({}, child.props, {
  544. path: path
  545. })) : context.match;
  546. }
  547. });
  548. return match ? React.cloneElement(element, {
  549. location: location,
  550. computedMatch: match
  551. }) : null;
  552. });
  553. };
  554. return Switch;
  555. }(React.Component);
  556. if (process.env.NODE_ENV !== "production") {
  557. Switch.propTypes = {
  558. children: PropTypes.node,
  559. location: PropTypes.object
  560. };
  561. Switch.prototype.componentDidUpdate = function (prevProps) {
  562. process.env.NODE_ENV !== "production" ? 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.') : void 0;
  563. process.env.NODE_ENV !== "production" ? 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.') : void 0;
  564. };
  565. }
  566. /**
  567. * A public higher-order component to access the imperative API
  568. */
  569. function withRouter(Component) {
  570. var displayName = "withRouter(" + (Component.displayName || Component.name) + ")";
  571. var C = function C(props) {
  572. var wrappedComponentRef = props.wrappedComponentRef,
  573. remainingProps = _objectWithoutPropertiesLoose(props, ["wrappedComponentRef"]);
  574. return React.createElement(context.Consumer, null, function (context) {
  575. !context ? process.env.NODE_ENV !== "production" ? invariant(false, "You should not use <" + displayName + " /> outside a <Router>") : invariant(false) : void 0;
  576. return React.createElement(Component, _extends({}, remainingProps, context, {
  577. ref: wrappedComponentRef
  578. }));
  579. });
  580. };
  581. C.displayName = displayName;
  582. C.WrappedComponent = Component;
  583. if (process.env.NODE_ENV !== "production") {
  584. C.propTypes = {
  585. wrappedComponentRef: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object])
  586. };
  587. }
  588. return hoistStatics(C, Component);
  589. }
  590. var useContext = React.useContext;
  591. function useHistory() {
  592. if (process.env.NODE_ENV !== "production") {
  593. !(typeof useContext === "function") ? process.env.NODE_ENV !== "production" ? invariant(false, "You must use React >= 16.8 in order to use useHistory()") : invariant(false) : void 0;
  594. }
  595. return useContext(historyContext);
  596. }
  597. function useLocation() {
  598. if (process.env.NODE_ENV !== "production") {
  599. !(typeof useContext === "function") ? process.env.NODE_ENV !== "production" ? invariant(false, "You must use React >= 16.8 in order to use useLocation()") : invariant(false) : void 0;
  600. }
  601. return useContext(context).location;
  602. }
  603. function useParams() {
  604. if (process.env.NODE_ENV !== "production") {
  605. !(typeof useContext === "function") ? process.env.NODE_ENV !== "production" ? invariant(false, "You must use React >= 16.8 in order to use useParams()") : invariant(false) : void 0;
  606. }
  607. var match = useContext(context).match;
  608. return match ? match.params : {};
  609. }
  610. function useRouteMatch(path) {
  611. if (process.env.NODE_ENV !== "production") {
  612. !(typeof useContext === "function") ? process.env.NODE_ENV !== "production" ? invariant(false, "You must use React >= 16.8 in order to use useRouteMatch()") : invariant(false) : void 0;
  613. }
  614. var location = useLocation();
  615. var match = useContext(context).match;
  616. return path ? matchPath(location.pathname, path) : match;
  617. }
  618. if (process.env.NODE_ENV !== "production") {
  619. if (typeof window !== "undefined") {
  620. var global = window;
  621. var key = "__react_router_build__";
  622. var buildNames = {
  623. cjs: "CommonJS",
  624. esm: "ES modules",
  625. umd: "UMD"
  626. };
  627. if (global[key] && global[key] !== "esm") {
  628. var initialBuildName = buildNames[global[key]];
  629. var secondaryBuildName = buildNames["esm"]; // TODO: Add link to article that explains in detail how to avoid
  630. // loading 2 different builds.
  631. throw new Error("You are loading the " + secondaryBuildName + " build of React Router " + ("on a page that is already running the " + initialBuildName + " ") + "build, so things won't work right.");
  632. }
  633. global[key] = "esm";
  634. }
  635. }
  636. export { MemoryRouter, Prompt, Redirect, Route, Router, StaticRouter, Switch, historyContext as __HistoryContext, context as __RouterContext, generatePath, matchPath, useHistory, useLocation, useParams, useRouteMatch, withRouter };
  637. //# sourceMappingURL=react-router.js.map