当用户在 React 页面上 30 秒内没有进行任何点击事件时,我正在努力创建注销功能

发布于 2025-01-14 12:59:55 字数 3520 浏览 0 评论 0原文

当用户在页面上 30 秒内没有进行任何点击事件时,我正在努力创建注销功能。

但是当用户点击页面上的任何内容时,剩余时间将再次重置为 30 秒(或者作为其他选项,将使用clearTimeOut和setTimeOut。)同时,当用户没有点击页面上的任何内容时,他们删除 accessToken 将在 30 秒后自动注销。

所以为了解决这个问题,我的做法是这样的:

  1. 当用户来到这个页面时,setTimeout()将开始。

  2. 当用户点击页面上的某些内容时,clearTimeOut 将被激活,setTimeOut 也会再次被激活

  3. 当用户在 30 秒内没有点击页面上的任何内容时,他们将通过删除 accessToken 来自动注销本地存储

目前,

  • 通过删除accessToken来使用户注销是可行的!
  • UseEffect 中的 setTimeOut 有效...

唯一的问题是

我不知道当用户在页面上单击事件时如何使clearTimeOut() 和 setTimeOut 工作..

import styled from 'styled-components';
import React, {useRef, useEffect, useState} from 'react';
import ScreenContainer from '../../src/component/common/ScreenContainer';
import {useNavigate as useDomNavigate} from 'react-router-dom';
import isNil from 'lodash/isNil';
import userClient from '../../src/client/user/userClient';

const Device = () => {
    const domNavigate = useDomNavigate();
    const [storeId, setStoreId] = useState(() => JSON.parse(localStorage.getItem('storeId')));
    const [currentDeposit, setCurrentDeposit] = useState<number>(0);
    const depositBalanceInfo = userClient.getDepositBalanceByStoreId(storeId, isNil(storeId)).data;

    const [time, setTime] = useState(1500);

    const logout = () => {
        localStorage.removeItem('accessToken');
        domNavigate(`/home/home`);
    };

    //////////////////////////
    // below is the code that I wrote to make it work..
 

    const myFunc = () => {
        // remove accessToken for logout
        localStorage.removeItem('accessToken');

        // move to home page
        domNavigate(`/home/home`);
    }

    // begin setTimeOut automatically when the users come over to this page from another one.
    useEffect(() => {
        const timeoutBegins = window.setTimeout(myFunc, 3000);
        return () => clearTimeout(timeoutBegins); 
    }, [])

    // when the users click anything on the page, it clears current setTimeOut function and restart the setTimeOut function again.
    const clickDisplay = () => {
        clearTimeout(timeoutBegins);
        timeOutBegins();
    }



   ///////////////////////////////////////// 

    useEffect(() => {
        if (storeId && depositBalanceInfo) {
            setCurrentDeposit(depositBalanceInfo?.depositBalance);
        }
    }, [storeId, depositBalanceInfo?.depositBalance]);

    return (
        <ScreenContainer>
            <Wrapper>
                <div>Choose Payment Option</div>
                <button onClick={() => window.history.back()}>go back</button>
                <div>Your Balance: {currentDeposit.toLocaleString()}dollar</div>
                <br />
                <button onClick={() => domNavigate(`/charge/step2-select-price/?chargeMethod=card`)}>Credit Card Payment</button>
                <br />
                <button onClick={() => domNavigate(`/charge/step2-select-price/?chargeMethod=cash`)}>Cash Payment</button>
                <br />
                <button onClick={() => domNavigate(`/home/checkUserByPin`)}>Reset Password</button>
                <br />
                <button onClick={logout}>Logout</button>
            </Wrapper>
        </ScreenContainer>
    );
};

const Wrapper = styled.div`
    border: 1px solid red;
`;

export default Device;

I'm struggling with creating a logout feature when users don't make any click event for 30 seconds on the page.

But when the users click anything on the page, the remaining time will be reset to 30 seconds again( or as an other option, clearTimeOut and setTimeOut will be used.) Meanwhile when the users don't click anything on the page, they are gonna be logged out automatically after 30seconds by removing the accessToken.

So to resolve the problem, my approach is like this:

  1. setTimeout() will be begun when the users come over to this page.

  2. when the users click something on the page, clearTimeOut will be active and setTimeOut will be active again too

  3. when the users don't click anything on the page for 30 seconds, they are gonna be logged out automatically by removing the accessToken in the local storage

Currently

  • Make the users logged out by removing the accessToken works!
  • setTimeOut in UseEffect works...

The only matters is

I have no idea how to make clearTimeOut() and setTimeOut work when the users make click event on the page..

import styled from 'styled-components';
import React, {useRef, useEffect, useState} from 'react';
import ScreenContainer from '../../src/component/common/ScreenContainer';
import {useNavigate as useDomNavigate} from 'react-router-dom';
import isNil from 'lodash/isNil';
import userClient from '../../src/client/user/userClient';

const Device = () => {
    const domNavigate = useDomNavigate();
    const [storeId, setStoreId] = useState(() => JSON.parse(localStorage.getItem('storeId')));
    const [currentDeposit, setCurrentDeposit] = useState<number>(0);
    const depositBalanceInfo = userClient.getDepositBalanceByStoreId(storeId, isNil(storeId)).data;

    const [time, setTime] = useState(1500);

    const logout = () => {
        localStorage.removeItem('accessToken');
        domNavigate(`/home/home`);
    };

    //////////////////////////
    // below is the code that I wrote to make it work..
 

    const myFunc = () => {
        // remove accessToken for logout
        localStorage.removeItem('accessToken');

        // move to home page
        domNavigate(`/home/home`);
    }

    // begin setTimeOut automatically when the users come over to this page from another one.
    useEffect(() => {
        const timeoutBegins = window.setTimeout(myFunc, 3000);
        return () => clearTimeout(timeoutBegins); 
    }, [])

    // when the users click anything on the page, it clears current setTimeOut function and restart the setTimeOut function again.
    const clickDisplay = () => {
        clearTimeout(timeoutBegins);
        timeOutBegins();
    }



   ///////////////////////////////////////// 

    useEffect(() => {
        if (storeId && depositBalanceInfo) {
            setCurrentDeposit(depositBalanceInfo?.depositBalance);
        }
    }, [storeId, depositBalanceInfo?.depositBalance]);

    return (
        <ScreenContainer>
            <Wrapper>
                <div>Choose Payment Option</div>
                <button onClick={() => window.history.back()}>go back</button>
                <div>Your Balance: {currentDeposit.toLocaleString()}dollar</div>
                <br />
                <button onClick={() => domNavigate(`/charge/step2-select-price/?chargeMethod=card`)}>Credit Card Payment</button>
                <br />
                <button onClick={() => domNavigate(`/charge/step2-select-price/?chargeMethod=cash`)}>Cash Payment</button>
                <br />
                <button onClick={() => domNavigate(`/home/checkUserByPin`)}>Reset Password</button>
                <br />
                <button onClick={logout}>Logout</button>
            </Wrapper>
        </ScreenContainer>
    );
};

const Wrapper = styled.div`
    border: 1px solid red;
`;

export default Device;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

霊感 2025-01-21 12:59:55

您可以在 useEffect 中添加用于单击的事件监听器

,它将运行您的函数并重置超时

 useEffect(() => {
      document.addEventListener("click", clickDisplay);
      return () => {}
 }, [])

you can add EventListener for click in useEffect

that will run your function and reset time out

 useEffect(() => {
      document.addEventListener("click", clickDisplay);
      return () => {}
 }, [])
季末如歌 2025-01-21 12:59:55
  • 方法 1

您可以在窗口中使用事件监听器


    const initIdleCheck = function (callback, timeLimit) {
      let time;
      window.onload = resetTimer;
      document.onload = resetTimer;
      document.onmousemove = resetTimer;
      document.onmousedown = resetTimer;
      document.ontouchstart = resetTimer;
      document.onclick = resetTimer;
      document.onkeypress = resetTimer;
      document.addEventListener('scroll', resetTimer, true);
      
      function resetTimer() {
        clearTimeout(time);
        time = setTimeout(callback, timeLimit)
      }
    };

    initIdleCheck(<IDLE_ACTION_FUNCTION>, <IDLE_TIME>);
    // IDLE_ACTION_FUNCTION - logout in your case

  • 方法 2

使用类似 idle-js。它提供相同的功能和自定义功能。

  • Method 1

You can use event listeners in window


    const initIdleCheck = function (callback, timeLimit) {
      let time;
      window.onload = resetTimer;
      document.onload = resetTimer;
      document.onmousemove = resetTimer;
      document.onmousedown = resetTimer;
      document.ontouchstart = resetTimer;
      document.onclick = resetTimer;
      document.onkeypress = resetTimer;
      document.addEventListener('scroll', resetTimer, true);
      
      function resetTimer() {
        clearTimeout(time);
        time = setTimeout(callback, timeLimit)
      }
    };

    initIdleCheck(<IDLE_ACTION_FUNCTION>, <IDLE_TIME>);
    // IDLE_ACTION_FUNCTION - logout in your case

  • Method 2

Use library like idle-js. It provides the same features with customizations.

策马西风 2025-01-21 12:59:55

您可以使用多种方法。让我们看一下其中的一个

    const [ isClicked , setIsClicked ] = useState(false)

    useEffect ( ()=> {
         const timer = setTimeOut( () => {
            if(isClicked) return;
            // do some thing
            window.history.back()
            // window.close()
         } , yourTime)
         
         return () => { clearTimeout(timer) }

    } , [])

   function onBtnClick () {
      setIsClicked(true)
   }

There are many approaches you can use. let's have a look at one of them

    const [ isClicked , setIsClicked ] = useState(false)

    useEffect ( ()=> {
         const timer = setTimeOut( () => {
            if(isClicked) return;
            // do some thing
            window.history.back()
            // window.close()
         } , yourTime)
         
         return () => { clearTimeout(timer) }

    } , [])

   function onBtnClick () {
      setIsClicked(true)
   }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文