-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
/
Switch.js
61 lines (51 loc) · 1.77 KB
/
Switch.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
import React from 'react'
import PropTypes from 'prop-types'
import warning from 'warning'
import invariant from 'invariant'
import matchPath from './matchPath'
/**
* The public API for rendering the first <Route> that matches.
*/
class Switch extends React.Component {
static contextTypes = {
router: PropTypes.shape({
route: PropTypes.object.isRequired
}).isRequired
}
static propTypes = {
children: PropTypes.node,
location: PropTypes.object
}
componentWillMount() {
invariant(
this.context.router,
'You should not use <Switch> outside a <Router>'
)
}
componentWillReceiveProps(nextProps) {
warning(
!(nextProps.location && !this.props.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(
!(!nextProps.location && this.props.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.'
)
}
render() {
const { route } = this.context.router
const { children } = this.props
const location = this.props.location || route.location
let match, child
React.Children.forEach(children, element => {
if (match == null && React.isValidElement(element)) {
const { path: pathProp, exact, strict, sensitive, from } = element.props
const path = pathProp || from
child = element
match = path ? matchPath(location.pathname, { path, exact, strict, sensitive }) : route.match
}
})
return match ? React.cloneElement(child, { location, computedMatch: match }) : null
}
}
export default Switch