React.js:使用功能组件和钩子的会话超时

时间:2020-05-28 08:26:05

标签: reactjs

我在使用类组件之前实现了会话超时功能

它工作正常,但是,我想将其转换为功能组件和挂钩

我在转换_onActiononActive等方面遇到麻烦。

如何保持程序检测到用户移动?

请参见下面的代码

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

1 个答案:

答案 0 :(得分:2)

这应该有效。如果您感到useReducer声明太多,也可以使用useState钩子。

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