Fix memory leak on mobile web tab navigation (#2021)
* Add navigationAction prop to Link * Bottom bar should use navigate() actionzio/stable
parent
bb9d340d42
commit
b778017000
|
@ -46,6 +46,7 @@ interface Props extends ComponentProps<typeof TouchableOpacity> {
|
||||||
noFeedback?: boolean
|
noFeedback?: boolean
|
||||||
asAnchor?: boolean
|
asAnchor?: boolean
|
||||||
anchorNoUnderline?: boolean
|
anchorNoUnderline?: boolean
|
||||||
|
navigationAction?: 'push' | 'replace' | 'navigate'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Link = memo(function Link({
|
export const Link = memo(function Link({
|
||||||
|
@ -58,6 +59,7 @@ export const Link = memo(function Link({
|
||||||
asAnchor,
|
asAnchor,
|
||||||
accessible,
|
accessible,
|
||||||
anchorNoUnderline,
|
anchorNoUnderline,
|
||||||
|
navigationAction,
|
||||||
...props
|
...props
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const {closeModal} = useModalControls()
|
const {closeModal} = useModalControls()
|
||||||
|
@ -67,10 +69,16 @@ export const Link = memo(function Link({
|
||||||
const onPress = React.useCallback(
|
const onPress = React.useCallback(
|
||||||
(e?: Event) => {
|
(e?: Event) => {
|
||||||
if (typeof href === 'string') {
|
if (typeof href === 'string') {
|
||||||
return onPressInner(closeModal, navigation, sanitizeUrl(href), e)
|
return onPressInner(
|
||||||
|
closeModal,
|
||||||
|
navigation,
|
||||||
|
sanitizeUrl(href),
|
||||||
|
navigationAction,
|
||||||
|
e,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[closeModal, navigation, href],
|
[closeModal, navigation, navigationAction, href],
|
||||||
)
|
)
|
||||||
|
|
||||||
if (noFeedback) {
|
if (noFeedback) {
|
||||||
|
@ -146,6 +154,7 @@ export const TextLink = memo(function TextLink({
|
||||||
title,
|
title,
|
||||||
onPress,
|
onPress,
|
||||||
warnOnMismatchingLabel,
|
warnOnMismatchingLabel,
|
||||||
|
navigationAction,
|
||||||
...orgProps
|
...orgProps
|
||||||
}: {
|
}: {
|
||||||
testID?: string
|
testID?: string
|
||||||
|
@ -158,6 +167,7 @@ export const TextLink = memo(function TextLink({
|
||||||
dataSet?: any
|
dataSet?: any
|
||||||
title?: string
|
title?: string
|
||||||
warnOnMismatchingLabel?: boolean
|
warnOnMismatchingLabel?: boolean
|
||||||
|
navigationAction?: 'push' | 'replace' | 'navigate'
|
||||||
} & TextProps) {
|
} & TextProps) {
|
||||||
const {...props} = useLinkProps({to: sanitizeUrl(href)})
|
const {...props} = useLinkProps({to: sanitizeUrl(href)})
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
@ -185,7 +195,13 @@ export const TextLink = memo(function TextLink({
|
||||||
// @ts-ignore function signature differs by platform -prf
|
// @ts-ignore function signature differs by platform -prf
|
||||||
return onPress()
|
return onPress()
|
||||||
}
|
}
|
||||||
return onPressInner(closeModal, navigation, sanitizeUrl(href), e)
|
return onPressInner(
|
||||||
|
closeModal,
|
||||||
|
navigation,
|
||||||
|
sanitizeUrl(href),
|
||||||
|
navigationAction,
|
||||||
|
e,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
onPress,
|
onPress,
|
||||||
|
@ -195,6 +211,7 @@ export const TextLink = memo(function TextLink({
|
||||||
href,
|
href,
|
||||||
text,
|
text,
|
||||||
warnOnMismatchingLabel,
|
warnOnMismatchingLabel,
|
||||||
|
navigationAction,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
const hrefAttrs = useMemo(() => {
|
const hrefAttrs = useMemo(() => {
|
||||||
|
@ -241,6 +258,7 @@ interface TextLinkOnWebOnlyProps extends TextProps {
|
||||||
accessibilityLabel?: string
|
accessibilityLabel?: string
|
||||||
accessibilityHint?: string
|
accessibilityHint?: string
|
||||||
title?: string
|
title?: string
|
||||||
|
navigationAction?: 'push' | 'replace' | 'navigate'
|
||||||
}
|
}
|
||||||
export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({
|
export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({
|
||||||
testID,
|
testID,
|
||||||
|
@ -250,6 +268,7 @@ export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({
|
||||||
text,
|
text,
|
||||||
numberOfLines,
|
numberOfLines,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
|
navigationAction,
|
||||||
...props
|
...props
|
||||||
}: TextLinkOnWebOnlyProps) {
|
}: TextLinkOnWebOnlyProps) {
|
||||||
if (isWeb) {
|
if (isWeb) {
|
||||||
|
@ -263,6 +282,7 @@ export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({
|
||||||
numberOfLines={numberOfLines}
|
numberOfLines={numberOfLines}
|
||||||
lineHeight={lineHeight}
|
lineHeight={lineHeight}
|
||||||
title={props.title}
|
title={props.title}
|
||||||
|
navigationAction={navigationAction}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -296,6 +316,7 @@ function onPressInner(
|
||||||
closeModal = () => {},
|
closeModal = () => {},
|
||||||
navigation: NavigationProp,
|
navigation: NavigationProp,
|
||||||
href: string,
|
href: string,
|
||||||
|
navigationAction: 'push' | 'replace' | 'navigate' = 'push',
|
||||||
e?: Event,
|
e?: Event,
|
||||||
) {
|
) {
|
||||||
let shouldHandle = false
|
let shouldHandle = false
|
||||||
|
@ -328,8 +349,18 @@ function onPressInner(
|
||||||
} else {
|
} else {
|
||||||
closeModal() // close any active modals
|
closeModal() // close any active modals
|
||||||
|
|
||||||
|
if (navigationAction === 'push') {
|
||||||
// @ts-ignore we're not able to type check on this one -prf
|
// @ts-ignore we're not able to type check on this one -prf
|
||||||
navigation.dispatch(StackActions.push(...router.matchPath(href)))
|
navigation.dispatch(StackActions.push(...router.matchPath(href)))
|
||||||
|
} else if (navigationAction === 'replace') {
|
||||||
|
// @ts-ignore we're not able to type check on this one -prf
|
||||||
|
navigation.dispatch(StackActions.replace(...router.matchPath(href)))
|
||||||
|
} else if (navigationAction === 'navigate') {
|
||||||
|
// @ts-ignore we're not able to type check on this one -prf
|
||||||
|
navigation.navigate(...router.matchPath(href))
|
||||||
|
} else {
|
||||||
|
throw Error('Unsupported navigator action.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ const NavItem: React.FC<{
|
||||||
: isTab(currentRoute.name, routeName)
|
: isTab(currentRoute.name, routeName)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={href} style={styles.ctrl}>
|
<Link href={href} style={styles.ctrl} navigationAction="navigate">
|
||||||
{children({isActive})}
|
{children({isActive})}
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue