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;
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;
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;
Hope these code blocks are helpful for your project...
Thank You! 🤗
Top comments (0)