[英]setTimeout and clearTimeout in React
但是每次用戶點擊頁面上的任何東西時,剩余時間必須重新設置為 30 秒(或者作為另一個選項,將使用 clearTimeOut 和 setTimeOut。)同時當用戶沒有點擊頁面上的任何東西時,他們將在 30 秒后通過刪除 accessToken 自動注銷。
所以要解決這個問題,我的做法是這樣的:
當用戶來到這個頁面時,setTimeout() 將開始。
當用戶單擊頁面上的某些內容時,clearTimeOut 將處於活動狀態並且 setTimeOut 也將再次處於活動狀態
當用戶在 30 秒內沒有點擊頁面上的任何內容時,他們將通過刪除本地存儲中的 accessToken 自動注銷
目前通過刪除 accessToken 使用戶在 30 秒后注銷。 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;
你可以做這樣的事情。 因此,您運行計時器,每次單擊文檔中的某處時,它都會取消當前計時器並運行新計時器。 因此,僅當用戶在 N 秒后未單擊該頁面時,您的myFunc
function 才會運行。
請記住,你想在 30 秒內完成,你需要將 30000 放入setTimeout
const timerId = useRef(null)
const myFunc = () => {
clearTimeout(timerId.current)
timerId.current = null
console.log('DO SOMETHING')
}
const onDocumentClick = () => {
if (timerId.current) {
clearTimeout(timerId.current)
timerId.current = window.setTimeout(myFunc, 3000)
}
}
useEffect(() => {
timerId.current = window.setTimeout(myFunc, 3000)
document.addEventListener('click', onDocumentClick)
return () => {
clearTimeout(timerId.current)
document.removeEventListener('click', onDocumentClick)
}
}, [])
從您的代碼片段中跳出幾個問題:
timeoutBegins
的范圍僅限於您的useEffect
回調,因此不可用於clickDisplay
。clickDisplay
未附加到任何事件偵聽器timeoutBegins
不可調用,它是定時器 ID注意:創建一個最小的可重現示例是個好主意,因為這將幫助您和審閱者消除問題。
解決方案:
let timerId;
function Device() {
const logOutUser = () => {
// log out code...
};
const startTimer = () => {
if (timerId) clearTimeout(timerId);
timerId = setTimeout(logOutUser, 3000);
}
const stopTimer = () => clearTimeout(timerId);
useEffect(() => {
// start timer when component is mounted
startTimer();
// stop timer when component is unmounted
return stopTimer;
}, []);
return <div onClick={startTimer}></div>;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.