UNPKG

1.96 kBJavaScriptView Raw
1import React from "react";
2import PropTypes from "prop-types";
3import { createLocation, locationsAreEqual } from "history";
4import invariant from "tiny-invariant";
5
6import Lifecycle from "./Lifecycle.js";
7import RouterContext from "./RouterContext.js";
8import generatePath from "./generatePath.js";
9
10/**
11 * The public API for navigating programmatically with a component.
12 */
13function Redirect({ computedMatch, to, push = false }) {
14 return (
15 <RouterContext.Consumer>
16 {context => {
17 invariant(context, "You should not use <Redirect> outside a <Router>");
18
19 const { history, staticContext } = context;
20
21 const method = push ? history.push : history.replace;
22 const location = createLocation(
23 computedMatch
24 ? typeof to === "string"
25 ? generatePath(to, computedMatch.params)
26 : {
27 ...to,
28 pathname: generatePath(to.pathname, computedMatch.params)
29 }
30 : to
31 );
32
33 // When rendering in a static context,
34 // set the new location immediately.
35 if (staticContext) {
36 method(location);
37 return null;
38 }
39
40 return (
41 <Lifecycle
42 onMount={() => {
43 method(location);
44 }}
45 onUpdate={(self, prevProps) => {
46 const prevLocation = createLocation(prevProps.to);
47 if (
48 !locationsAreEqual(prevLocation, {
49 ...location,
50 key: prevLocation.key
51 })
52 ) {
53 method(location);
54 }
55 }}
56 to={to}
57 />
58 );
59 }}
60 </RouterContext.Consumer>
61 );
62}
63
64if (__DEV__) {
65 Redirect.propTypes = {
66 push: PropTypes.bool,
67 from: PropTypes.string,
68 to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired
69 };
70}
71
72export default Redirect;