I have a requirement to display timeout warning modal after 13 mins of inactivity and end session after 15 mins if user takes no action. I need to achieve this using reactjs. I checked react-timeout at https://www.npmjs.com/package/react-timeout#react-classic-verbose, but that didn't help. If anyone knows of a way to do this, please share with me.
-
1Off the top of my head, why not define an `active` property in the component's `state`. Set a timeout via `setTimeout` to set the `active` to `false` after 13 minutes of inactivity. Everytime the user moves the mouse / touches the screen, reset the timeout. In the main app component, you can do something similar to end a session. – Raphael Rafatpanah Mar 31 '17 at 02:18
3 Answers
You can create a higher order component like this and can pass child component through higher order component
HOC:
`// code
export default function(ComposedClass) {
class AutoLogout extends React.Component {
constructor(props) {
super(props);
this.state = {
warningTime: 1000 * 60 * 10,
signoutTime: 1000 * 60 * 15,
};
}
componentDidMount() {
this.events = [
'load',
'mousemove',
'mousedown',
'click',
'scroll',
'keypress'
];
for (var i in this.events) {
window.addEventListener(this.events[i], this.resetTimeout);
}
this.setTimeout();
}
clearTimeoutFunc = () => {
if (this.warnTimeout) clearTimeout(this.warnTimeout);
if (this.logoutTimeout) clearTimeout(this.logoutTimeout);
};
setTimeout = () => {
this.warnTimeout = setTimeout(this.warn, this.state.warningTime);
this.logoutTimeout = setTimeout(this.logout, this.state.signoutTime);
};
resetTimeout = () => {
this.clearTimeoutFunc();
this.setTimeout();
};
warn = () => {
window.alert("You will be logged out automatically in 1 minute")
console.log('You will be logged out automatically in 1 minute.');
};
logout = () => {
// Send a logout request to the API
console.log('Sending a logout request to the API...');
this.destroy();
};
destroy = () => {
//clear the session
browserHistory.push('/');
window.location.assign('/');
};
render() {
return (
<div>
<ComposedClass {...this.props} />
</div>
);
}
}
}
`
You can wrap this HOC to all those component in which you want to give user warning due to inactivity, in routing file
<Route path="/test" component={HOC(comonent)} />
in above code component will be the page where you want to add this functionality.

- 765
- 7
- 15
-
-
1
-
https://stackoverflow.com/users/3368818/j-woodchuck - did you get this work ? If so, can you post your solution? – MLissCetrus Mar 02 '20 at 15:46
-
I am getting this: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. – MLissCetrus Mar 02 '20 at 16:13
-
Here is a full example of the modal idle warning.
Assuming you are using reactstrap for styling here is the example.
import React, {useState, useEffect} from 'react';
import {Modal, ModalHeader, ModalBody, ModalFooter} from 'reactstrap';
function IdleMonitor()
{
//Modal
const [idleModal, setIdleModal] = useState(false);
let idleTimeout = 1000 * 60 * 1; //1 minute
let idleLogout = 1000 * 60 * 2; //2 Minutes
let idleEvent;
let idleLogoutEvent;
/**
* Add any other events listeners here
*/
const events = [
'mousemove',
'click',
'keypress'
];
/**
* @method sessionTimeout
* This function is called with each event listener to set a timeout or clear a timeout.
*/
const sessionTimeout = () =>
{
if(!!idleEvent) clearTimeout(idleEvent);
if(!!idleLogoutEvent) clearTimeout(idleLogoutEvent);
idleEvent = setTimeout(() => setIdleModal(true), idleTimeout); //show session warning modal.
idleLogoutEvent = setTimeout(() => logOut, idleLogout); //Call logged out on session expire.
};
/**
* @method extendSession
* This function will extend current user session.
*/
const extendSession = () =>
{
console.log('user wants to stay logged in');
}
/**
* @method logOut
* This function will destroy current user session.
*/
const logOut = () =>
{
console.log('logging out');
}
useEffect(() =>
{
for (let e in events)
{
window.addEventListener(events[e], sessionTimeout);
}
return () =>
{
for(let e in events)
{
window.removeEventListener(events[e], sessionTimeout);
}
}
},[]);
return (
<Modal isOpen={idleModal} toggle={() => setIdleModal(false)}>
<ModalHeader toggle={() => setIdleModal(false)}>
Session expire warning
</ModalHeader>
<ModalBody>
your session will expire in {idleLogout / 60 / 1000} minutes. Do you want to extend the session?
</ModalBody>
<ModalFooter>
<button className="btn btn-info" onClick={()=> logOut()}>Logout</button>
<button className="btn btn-success" onClick={()=> extendSession()}>Extend session</button>
</ModalFooter>
</Modal>
)
}
export default IdleMonitor;
after you create that class you can simply call it from anywhere like this
<IdleMonitor/>
don't forget to import it.

- 3,863
- 1
- 27
- 17
If you want to achieve same with Package, then you can write below code using React Idle Timer Package
npm i react-idle-timer
import React from 'react'
import { useIdleTimer } from 'react-idle-timer'
import { useHistory } from 'react-router'
const SESSION_IDEL_MINUTES = 4;
const AutoLagoutTimer = (props: any) => {
const { ComposedClass } = props
const history = useHistory()
const handleOnIdle = (event: any) => {
// SHOW YOUR MODAL HERE AND LAGOUT
console.log('user is idle', event)
console.log('last active', getLastActiveTime())
history.push("/lagout")
}
const {getLastActiveTime } = useIdleTimer({
timeout: 1000 * 60 * SESSION_IDEL_MINUTES,
onIdle: handleOnIdle,
debounce: 500,
})
return <ComposedClass />
}
export default AutoLagoutTimer;
And for all your protected routes you can wrap with this component like below
<Route path={"/dashboard"}>
<AutoLagoutTimer ComposedClass={Dashboard} />
</Route>

- 909
- 7
- 11