-
-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathLink.js
80 lines (67 loc) · 2.02 KB
/
Link.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
import React from 'react'
import PropTypes from 'prop-types'
import invariant from 'invariant'
import { createLocation } from 'history'
const isModifiedEvent = (event) =>
!!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey)
/**
* The public API for rendering a history-aware <a>.
*/
class Link extends React.Component {
static propTypes = {
onClick: PropTypes.func,
target: PropTypes.string,
replace: PropTypes.bool,
to: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
]).isRequired,
innerRef: PropTypes.oneOfType([
PropTypes.string,
PropTypes.func
])
}
static defaultProps = {
replace: false
}
static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired,
createHref: PropTypes.func.isRequired
}).isRequired
}).isRequired
}
handleClick = (event) => {
if (this.props.onClick)
this.props.onClick(event)
if (
!event.defaultPrevented && // onClick prevented default
event.button === 0 && // ignore everything but left clicks
!this.props.target && // let browser handle "target=_blank" etc.
!isModifiedEvent(event) // ignore clicks with modifier keys
) {
event.preventDefault()
const { history } = this.context.router
const { replace, to } = this.props
if (replace) {
history.replace(to)
} else {
history.push(to)
}
}
}
render() {
const { replace, to, innerRef, ...props } = this.props // eslint-disable-line no-unused-vars
invariant(
this.context.router,
'You should not use <Link> outside a <Router>'
)
const { history } = this.context.router
const location = typeof to === 'string' ? createLocation(to, null, null, history.location) : to
const href = history.createHref(location)
return <a {...props} onClick={this.handleClick} href={href} ref={innerRef}/>
}
}
export default Link