DEV Community

Cover image for React useUndo hook
Bhavesh Mishra
Bhavesh Mishra

Posted on • Updated on

React useUndo hook

I am totally new in web development and this is my first blog, any sorts of suggestion or comments is welcome and that will help me to learn and grow.
So lets start with the useUndo hook.
Last week in our organization came with a requirement that we need to have a card that will have two options Accept and Decline, and after selecting any one of the option we will be giving the user a time period of let say 10 sec and with in this period they can undo their action.

eg --->

alt text

If they accept/ delete

alt text

So what i thought is to make a undo function which can help me with with this and also if i would like to use this undo function anywhere anywhere i will use it. So i came up with an useUndo hook, which was possible with React lifecycle

so lets discuss with the code and how i had implemented it.

First i will show the full code and then i will break it in different part and discuss about each of them.

Alt Text

First i have used useState react hook to

  1. Invoke the undo function
  2. store the timeout id
  3. to check if the method execution is finished or not.

alt text

Next is the onUnload event-lisitener function
alt text

what this will do is it will throw and alert if you are trying to close the tab or window. We are doing this because as we are using setTimeout and clearTimeout so these are window scoped and each time we close or open a new tab a new scope is created so if we close the tab the the setTimeout which are web-api will be cleared from the call back queue and will not enter in the execution stack even after the time interval is over.
alt text

Hence we will listen for an event-listener i.e beforeunload.

Next the most important part according to me in this code is the useEffect part i.e

alt text

So what we are doing here is

  1. First we check if invokeUndo is true or not and if so we add an event listener beforeunload on window. then we put our function inside the timeout which will be executed after 10000ms i.e 10s. Now the setTimeout web-api return a uniq number everytime you run it, which will be used to clear the timeout fucnction.

Inside the setTimeout we call the function which is resolveMethod() set the undoTimerId to null as the function execution is finished, setMethodExecuted to true which will be returned value and while using the hook if we have any action to perform after execution can be done, & setInvokeUndo(false) as the execution is finished.

Now the important part we need to do some clean-up on component-unmount so we will have a return statement in useEffect which will clear eventListener.

Now to invoke the undo we have invokeUndoMethod which will be a returned value and while using this hook we can use this.

we have an undoMethod which will perform the undo method i.e clearTimeout, setInvokeUndo to false.

alt text

Now we will have a final return statement

alt text

  1. undoMethod to perform the undo action
  2. invokeUndoMethod to invoke the undo or start undo method
  3. isMethodExecuted this will tell if the method execution is completed or not.

Now while using it.

alt text

we can import this useUndo hook and pass inside the onAcceptance method we need to be executed after 10s.

That's All folks 😃

Update ---> github repo link

https://github.com/mishrabhavesh/useUndo

Discussion (5)

Collapse
sidmirza4 profile image
Mohd Shahid

Nice article,
but a suggestion is that you could have used code in md instead of pictures.

Collapse
mishrabhavesh profile image
Bhavesh Mishra Author

Will update the blog with the github repo link.

Collapse
optimbro profile image
Rahul

Bahot badhiyaa

Collapse
akshaay9 profile image
Akshaay9

Use useRef for storing timerID, or useCallback it

Collapse
sneakysensei profile image
Snehil

I second this. Although I'm not sure how can one useCallback a timer. Can you pls provide an example snippet?