-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
/
Redirect.js
101 lines (85 loc) · 2.15 KB
/
Redirect.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import React from 'react'
import PropTypes from 'prop-types'
import warning from 'warning'
import invariant from 'invariant'
import { createLocation, locationsAreEqual } from 'history'
import generatePath from './generatePath'
/**
* The public API for updating the location programmatically
* with a component.
*/
class Redirect extends React.Component {
static propTypes = {
computedMatch: PropTypes.object, // private, from <Switch>
push: PropTypes.bool,
from: PropTypes.string,
to: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
]).isRequired
}
static defaultProps = {
push: false
}
static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired
}).isRequired,
staticContext: PropTypes.object
}).isRequired
}
isStatic() {
return this.context.router && this.context.router.staticContext
}
componentWillMount() {
invariant(
this.context.router,
'You should not use <Redirect> outside a <Router>'
)
if (this.isStatic())
this.perform()
}
componentDidMount() {
if (!this.isStatic())
this.perform()
}
componentDidUpdate(prevProps) {
const prevTo = createLocation(prevProps.to)
const nextTo = createLocation(this.props.to)
if (locationsAreEqual(prevTo, nextTo)) {
warning(false, `You tried to redirect to the same route you're currently on: ` +
`"${nextTo.pathname}${nextTo.search}"`)
return
}
this.perform()
}
computeTo({ computedMatch, to }) {
if (computedMatch) {
if (typeof to === "string") {
return generatePath(to, computedMatch.params)
} else {
return {
...to,
pathname: generatePath(to.pathname, computedMatch.params)
}
}
}
return to
}
perform() {
const { history } = this.context.router
const { push } = this.props
const to = this.computeTo(this.props)
if (push) {
history.push(to)
} else {
history.replace(to)
}
}
render() {
return null
}
}
export default Redirect