I am opening a url in webview. On opening the webview (let say page A), when i traverse or go inside any other options by clicking some options, some other page gets opened (let say page B). Now when i click on the hardware back option, i want to return to the previous screens that is (page A). And again n clicking back, i want to return into my app.
Tried following,
const [canGoBack, setCanGoBack] = useState(false);
const WebViewRef = useRef<WebView>(null);
useEffect(() => {
if (Platform.OS === "android") {
BackHandler.addEventListener("hardwareBackPress", HandleBackPressed);
return () => {
BackHandler.removeEventListener("hardwareBackPress", HandleBackPressed);
};
}
}, []);
<WebView
ref={WebViewRef}
// onLoadStart={() => setLoading!(true)}
onLoadEnd={() => setLoading!(false)}
source={{ uri: props.navigation.getParam("x") }}
onNavigationStateChange={(data) => handleResponse(data, WebViewRef)}
/>;
const handleResponse = (data: NavState, WebViewRef: any) => {
console.log(data.canGoBack); // <- always false, if i can go back further back or not in a webview
setCanGoBack(data?.canGoBack!);
};
const HandleBackPressed = () => {
if (WebViewRef.current && canGoBack) {
WebViewRef.current.goBack();
return true; // PREVENT DEFAULT BEHAVIOUR (EXITING THE APP)
}
return false;
};
How to achieve it?
In your code, the canGoBack
updates are not reflected in the backHandler method since the useEffect only gets run on init.
You can make that effect depend on the canGoBack as follows:
React.useEffect(() => {
if (Platform.OS === 'android') {
const backHandler = BackHandler.addEventListener(
'hardwareBackPress',
() => {
if (webViewRef.current && canGoBack) {
webViewRef.current.goBack();
return true; // PREVENT DEFAULT BEHAVIOUR (EXITING THE APP)
}
return false;
}
);
return () => backHandler.remove();
}
}, [canGoBack]);
You can see a working snack example here: https://snack.expo.io/QcYE9CTaO
It would be a bit cleaner if you can wrapped the backHandler method in a useCallback
so that depends on the state value and then a useEffect that depends on the new backHandler
.