I am now developing the React Native app with the WebView. I have some links from emails that can lead to my website. In that case I want to open my app that is installed and open the WebView with that link from email.
It works for me just fine by using Linking.addEventListener('url', ({url}) => ...)
subscription.
The problem is when I try to open the same link again, it just doesn't navigate there. I need to open link B if I want to open link A again. It looks like the cache issue. Or simple react state update thing. The url is the same, so component doesn't re-render anything (maybe). I tried to use a key prop additionally to make sure WebView re-renders when key changes. No luck with that as well.
Can someone suggest the workaround for that? Is it a known issue?
I tried a lot of solutions but the thing is that the handshake only works with production, so I need to upload new version and wait some time after it appears in market.
My code is super simple:
...
const [initialUrl, setInitialUrl] = useState<string | null>(null)
...
const handleNavigationStateChange = (navState: any) => {
setCanGoBack(navState.canGoBack)
}
const handleShouldStartLoadWithRequest = (navState: any) => {
if (navState.url && !navState.url.startsWith(targetUrl)) {
if (navState.url.match(/^(https?|mailto|tel|sms|geo):/i)) {
Linking.openURL(navState.url).then()
return false
}
}
return true
}
...
useEffect(() => {
let finalUrl = `${targetUrl}/auth/login`
const checkAndSetUrl = async () => {
const initialLink = await Linking.getInitialURL()
if (initialLink) {
finalUrl = initialLink
console.log('App opened with Deep Link URL:', initialLink)
} else {
try {
const value = await AsyncStorage.getItem(FIRST_LOAD_KEY)
if (value === null) {
finalUrl = `${targetUrl}/auth/start` // Onboarding
await AsyncStorage.setItem(FIRST_LOAD_KEY, 'false')
}
} catch (e) {
console.error('Failed to read/save data:', e)
}
}
setInitialUrl(finalUrl)
}
checkAndSetUrl()
const subscription = Linking.addEventListener('url', ({ url }) => {
setInitialUrl(url)
})
return () => {
subscription.remove()
}
}, [targetUrl])
...
return (
<SafeAreaWrapper>
<WebView
ref={webViewRef}
applicationNameForUserAgent={'APP'}
cacheEnabled={false}
source={{ uri: initialUrl }}
style={styles.webview}
onError={onError}
onShouldStartLoadWithRequest={handleShouldStartLoadWithRequest}
onNavigationStateChange={handleNavigationStateChange}
/>
</SafeAreaWrapper>
)
I expect the URL to work every time, not only the first time. It should navigate to the specified location after I click the link again.
UPDATE
I have found the fix myself. It was indeed the react state issue. I added the timestamp param to the url before setting it in the handler and it works now every time.
const subscription = Linking.addEventListener('url', ({ url }) => {
const separator = url.includes('?') ? '&' : '?'
const newUrl = `${url}${separator}t=${Date.now()}`
setInitialUrl(newUrl)
})