-
Notifications
You must be signed in to change notification settings - Fork 583
/
Copy pathRouterLink.tsx
67 lines (56 loc) · 1.77 KB
/
RouterLink.tsx
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
import { TouchableProps } from "@artsy/palette-mobile"
import { navigate } from "app/system/navigation/navigate"
import { Sentinel } from "app/utils/Sentinel"
import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag"
import { usePrefetch } from "app/utils/queryPrefetching"
import { useState } from "react"
import { GestureResponderEvent, TouchableOpacity } from "react-native"
interface RouterLinkProps {
disablePrefetch?: boolean
navigationProps?: Object
to?: string | null | undefined
}
/**
* Wrapper component around <Touchable> that navigates to a specified route (the `to` prop) when pressed.
* `RouterLink` also supports prefetching the route when it comes into view.
*/
export const RouterLink: React.FC<RouterLinkProps & TouchableProps> = ({
disablePrefetch,
to,
onPress,
navigationProps,
...restProps
}) => {
const [isPrefetched, setIsPrefetched] = useState(false)
const prefetchUrl = usePrefetch()
const enableViewPortPrefetching = useFeatureFlag("AREnableViewPortPrefetching")
const isPrefetchingEnabled = !disablePrefetch && enableViewPortPrefetching && to
const handlePress = (event: GestureResponderEvent) => {
onPress?.(event)
if (!to) return
if (navigationProps) {
navigate(to, { passProps: navigationProps })
} else {
navigate(to)
}
}
const handleVisible = (isVisible: boolean) => {
if (isPrefetchingEnabled && isVisible && !isPrefetched) {
prefetchUrl(to)
setIsPrefetched(true)
}
}
const touchableProps = {
activeOpacity: 0.65,
onPress: handlePress,
...restProps,
}
if (!isPrefetchingEnabled) {
return <TouchableOpacity {...touchableProps} />
}
return (
<Sentinel onChange={handleVisible}>
<TouchableOpacity {...touchableProps} />
</Sentinel>
)
}