How to listen to navigate event? - reactjs

Problem: I would like to use callback functions based on changes in href when user navigates within the same page.
For example, i would like to use a callback when a user navigates out of the component (changing href from localhost:3000/user to localhost:3000/about)
I've tried
popstate (which works when using forward/backward)
unload(works when i refresh)
pagehide/pageshow did not seem to respond at all.
visibilitychange fired whenever i moved out of the tab, but it was not what I was looking for.

You can use the useEffect cleanup function to trigger logic when the component unmounts.
useEffect(() => {
effect
return () => {
cleanup
}
}, [input])

Related

Browser.addEventListener of cordoba not fire setState within listenerFunc

I am using React with Ionic to build an app. I have a method that calls Browser.open to open InAppBrowser for external URL. I am adding a listener when the browser closes with Browser.addEventListener and effectively the functenerFunc runs but for some reason, the function does not fire some setState and dispatch called within that function.
const [someBoolean, setSomeBoolean] = useState<boolean>(false);
const openWindows = (url) => {
Browser.addListener('browserFinished', () => {
// This console log fires when the browser is closed
console.log('start');
// Those methods does not fire when the browser is closed
setSomeBoolean(true)
dispatch(someImportedReactAction('RS2'));
console.log('finish')
Browser.removeAllListeners()
})
Browser.open({
url: url
})
}
As you can see in the code above, the first console.log fires with no problem, but after that, it seems that the function stops and nothing happened. setSomeBoolean and the dispatch do not fire.
Any ideas why?

How to make an onclick automatically happen after 2 minutes in ReactJS Typescript

I am planning to make a buttons onClick function automatic after 2 minutes. This is my current button and the function I am calling is handle event videos.
How can I trigger that the button is automatically clicked after 2 minutes. I planned to create a new function and call the handleEventVideos() in there and then pass that function in useEffect. But that doesn't work. Can anyone please help me how I can do this?
<Button
disabled={isDisable}
type="submit"
onClick={() => handleEventVideos()}
variant="contained"
className={classes.doneButton}
>
Done
</Button>
if you want to cal the onclick function in you sample, you can use setTimeout and call handleEventVideos function. It would be something like this:
document.addEventListener('DOMContentLoaded', function() {
setTimeout(()=>{
alert("your function of interest!")
},2000);
});
However, it would be the case if you do not need the event variable in your function (like you example here). However, if you want to invoke the react click event by defining a ref and calling its click function. You can find an extended solution here:
How to manually trigger click event in ReactJS?
In case you wanted to call it with 2 second delay, you just have to use setTimeout function in the same fashion it is used above.
This alert will pop up after 2 minutes. Instead of alert you can put
your onclick function there.
const OnClick =()=> {
setTimeout(()=>{
alert("I will pop up after 2 minutes")
},20000);
});

React hook cleanup when refreshing the page

I have an app built in React using hooks that when closed needs to notify the server. I tried doing it using the following approach:
function onUnload() {
if (roomID !== "")
endGame(roomID, dispatch);
}
useEffect(() => {
return onUnload;
},[])
Here, endGame is a function that performs a HTTP request to the backend. But when refreshing the page to emulate a user closing the app, the request never reaches the server, meaning that the cleanup function doesn't get executed. Any ideas on what is wrong?
Thanks in advance
Refreshing the page is not same as component unmount. When you refresh the page, the React state is reset as React solely works on the current client session and refresh is equivalent to resetting it. What you are lloking for might be the onunload event. Try this:
window.onbeforeunload = function(e) {
return onUnload();
};

$location.path not navigating propertly within $locationChangeStart callback

In order to prevent view changes on a form with edits, I am using $locationChangeStart to intercept the view change. In that function, I am attempting to use a bootstrap dialog to prompt the user.
It all works ok, until the part where I call $location.path(current) to change the view. Instead of navigation to the appropriate route, it goes to the default route (the home page). Why is this?
Here is the code I am using in my controller:
function onNavigate() {
var turnOff = $scope.$on('$locationChangeStart',
function (event, current, previous) {
if (vm.canSave) {
dialogService.confirmationDialog('Are you sure?', 'You have unsaved changes, are you sure you want to abandon your form?')
.then(function() {
turnOff();
$location.path(current);
});
event.preventDefault();
});
}
In the debugger, the value of current is something like
http://localhost:3091/#/participant/24
at the $location.path line, however my application ends up at
http://localhost:3091/#/

Warn user before navigating to a different view

I would like to warn user and get a confirmation before the user navigates away from certain pages in my application, like composing a new message view. Which events can i capture and cancel/continue to make this happen ?
You should handle the $locationChangeStart event in order to hook up to view transition event, so use this code to handle the transition validation in your controller/s:
$scope.$on('$locationChangeStart', function( event ) {
var answer = confirm("Are you sure you want to leave this page?")
if (!answer) {
event.preventDefault();
}
}
also you can use this directive angularjs-unsaved-changes which would be much more reusable than writing it per controller..
If you have say a link or button navigating to another route or state, you could simply show a modal confirming the navigation:
Go Away...
$scope.goToAnotherState = function(){
//show modal and get confirmating however your like
if(modalResponse.Ok){
$state.go('anotherState');
}
}
another option would be to do this in the $locationChangeStart event of ui-router, but if you're looking to this only here n there, then the first approach is better. $locationChangeStart approach:
$rootScope.$on('$locationChangeStart', function (event, next, prev) {
event.preventDefault();
//show modal
if(modalResponse.ok){
var destination = next.substr(next.indexOf('#') + 1, next.length).trim();
$location.path(destination)
}
}
When defining a state, use the onExit callback, which is a transition hook:
An onEnter/onExit declared on a state is processed as a standard Transition Hook. The return value of a hook may alter a transition.
.state('foo', {
//dont return a value else it the transition will wait on the result to resolve (Promise)
onEnter: (MyService) => { MyService.doThing(); },
//return false to cancel the transition; i.e. prevent user from leaving
onExit: (MyService) => { return MyService.isSatisfied(); }
});
https://ui-router.github.io/ng1/docs/latest/interfaces/ng1.ng1statedeclaration.html#onexit

Resources