DEV Community

taiseen
taiseen

Posted on

detect user ⬅️ back button click, when background task is 🔄️ running...

We accomplish this behavioral need by the help of 3 things...
1. ParentComponent .jsx
2. ModalComponent .jsx || ChildComponent .jsx
3. useBackButtonClick .js <-- custom hook

[NOTE: CSS Missing...]


1. ParentComponent.jsx

import useBackButtonClick from '../utils/useBackButtonClick';
import ModalComponent from '../utils/ModalComponent';
import { useState } from 'react';

const ParentComponent = () => {

  const [isAiTaskDialog, setIsAiTaskDialog] = useState(false);

  // custom hook call for back button click...
  const handleCloseAiRequest = useBackButtonClick(setIsAiTaskDialog);

  return (
    <div>
      ... ... 
      <ModalComponent
        visible={isAiTaskDialog}
        onClose={() => setIsAiTaskDialog(false)}
        onOk={handleCloseAiRequest}
      />

    </div>
  );
};

export default ParentComponent;
Enter fullscreen mode Exit fullscreen mode

2. ModalComponent.jsx

const ModalComponent = ({ onClose, onLeave, visible = false }) => {

  return (
    <div style={{ display: visible ? 'block' : 'none' }}>
      <div>

        <h3>Background operation is in progress!</h3>
        <p> Are sure that you want to leave? </p>
        <div>
          <button onClick={onLeave}> Leave </button>
          <button onClick={onClose}> Stay </button>
        </div>

      </div>
    </div>
  );
};

export default ModalComponent;
Enter fullscreen mode Exit fullscreen mode

3. useBackButtonClick.js

import { useCallback, useEffect, useState } from 'react';
import { taskInProgress } from '../../services/memory';
import { useHistory } from 'react-router-dom';

// this hook is created only for Back-Button-Click.
function useBackButtonClick(callback) {

  const history = useHistory();
  const [triggerExit, setTriggerExit] = useState(
        { onLeave: false, path: '' }
  );

  const handleBackButton = useCallback(
        (location) => history.push(location), [history]
  );

  const handleCloseAiRequest = () => {
    setTriggerExit((obj) => ({ ...obj, onLeave: true }));
    callback(false);
  };

  useEffect(() => {

    if (triggerExit.onLeave) handleBackButton(triggerExit.path);

    const unblock = history.block((location) => {

      // if task is running at background...
      if (taskInProgress.status) {

        if (location?.pathname !== '') callback(true);

        setTriggerExit(obj => ({...obj, path: location?.pathname}));

        return triggerExit.onLeave;
      }
    });

    return () => unblock();
  }, [
      triggerExit.onLeave, 
      triggerExit.path, 
      handleBackButton, 
      callback,
      history,
     ]
 );

  return handleCloseAiRequest;
}

export default useBackButtonClick;
Enter fullscreen mode Exit fullscreen mode

Hope these code blocks are helpful for your project...
Thank You! 🤗

Top comments (0)