Reputation: 404
I implemented a session timeout function before using class component
It is working fine, however, I want to convert it to functional component and hooks
I'm having trouble especially converting _onAction
, onActive
, etc.
How do I maintain that the program detects user movement?
Kindly see code below
import React, { Component } from 'react'
import TopNavigation from '../topNavigation'
import SideNavigation from '../sideNavigation'
import Routes from '../Routes'
import Footer from '../Footer'
import IdleTimer from 'react-idle-timer'
import { IdleTimeOutModal } from '../modals/IdleTimeoutModal'
import PropertyService from '../../services/PropertyService'
class AuthenticatedPage extends Component {
constructor(props){
super(props)
this.state = {
timeout: 1000 * 60 * 15, /*15 mins - Initial value only, final is from property file*/
showModal: false,
userLoggedIn: false,
isTimedOut: false
}
this.idleTimer = null
this.onAction = this._onAction.bind(this)
this.onActive = this._onActive.bind(this)
this.onIdle = this._onIdle.bind(this)
this.handleClose = this.handleClose.bind(this)
this.handleLogout = this.handleLogout.bind(this)
}
_onAction(e) {
this.setState({isTimedOut: false})
}
_onActive(e) {
this.setState({isTimedOut: false})
}
_onIdle(e) {
const isTimedOut = this.state.isTimedOut
if (isTimedOut) {
} else {
this.setState({showModal: true})
this.idleTimer.reset();
this.setState({isTimedOut: true})
}
}
handleClose() {
this.setState({showModal: false})
}
handleLogout() {
this.setState({
showModal: false
});
this.props.history.push('/')
}
componentWillMount(){ /* should be called not only once */
PropertyService
.retrieveAllProperties()
.then((response) => {
this.setState({ timeout: response.data.timeout })
})
}
render() {
const { match } = this.props
return (
<React.Fragment>
<IdleTimer
ref={ref => { this.idleTimer = ref }}
element={document}
onActive={this.onActive}
onIdle={this.onIdle}
onAction={this.onAction}
debounce={250}
timeout={this.state.timeout} />
<div>
<TopNavigation />
<SideNavigation />
<main id="content" className="p-5">
<Routes />
</main>
<Footer />
</div>
<IdleTimeOutModal
showModal={this.state.showModal}
handleClose={this.handleClose}
handleLogout={this.handleLogout}
/>
</React.Fragment>
)
}
}
export default AuthenticatedPage
Upvotes: 0
Views: 2721
Reputation: 4205
This should work. You can also use useReducer
hook if you're feeling that there are too many useState
declarations.
import React, { useState, useEffect, useRef } from 'react'
import TopNavigation from '../topNavigation'
import SideNavigation from '../sideNavigation'
import Routes from '../Routes'
import Footer from '../Footer'
import IdleTimer from 'react-idle-timer'
import { IdleTimeOutModal } from '../modals/IdleTimeoutModal'
import PropertyService from '../../services/PropertyService'
const AuthenticatedPage = ({
history
}) => {
const [timeoutDuration, setTimeoutDuration] = useState(1000 * 60 * 15);
const [showModal, setShowModal] = useState(false);
const [userLoggedIn, setUserLoggedIn] = useState(false);
const [isTimedOut, setIsTimedOut] = useState(false);
const idleTimer = useRef();
const onAction = () => {
setIsTimedOut(false);
}
const onActive = (e) => {
setIsTimedOut(false);
}
const onIdle = (e) => {
if (!isTimedOut) {
setShowModal(true)
idleTimer.current.reset();
setIsTimedOut(true);
}
}
const handleClose = () => {
setShowModal(false);
}
const handleLogout = () => {
setShowModal(false);
history.push('/')
}
useEffect(() => {
PropertyService
.retrieveAllProperties()
.then((response) => {
setTimeoutDuration(response.data.timeout);
})
}, []);
return (
<React.Fragment>
<IdleTimer
ref={idleTimer}
element={document}
onActive={onActive}
onIdle={onIdle}
onAction={onAction}
debounce={250}
timeout={timeoutDuration} />
<div>
<TopNavigation />
<SideNavigation />
<main id="content" className="p-5">
<Routes />
</main>
<Footer />
</div>
<IdleTimeOutModal
showModal={showModal}
handleClose={handleClose}
handleLogout={handleLogout}
/>
</React.Fragment>
)
}
export default AuthenticatedPage
Upvotes: 3