React - 将 class 组件转换为会话的功能组件

React - Convert class component to functional component for session

在 React 应用程序中,我正在尝试通过引用 https://medium.com/tinyso/how-to-detect-inactive-user-to-auto-logout-by-using-idle-timeout-in-javascript-react-angular-and-b6279663acf2

为非活动用户(会话)自动注销

现在,如果我尝试将 class 组件的代码更改为功能代码,它将无法像以前那样工作。

Class 组件代码将从 https://codesandbox.io/s/suspicious-dream-w1cyc?from-embed

获取

函数组件代码如下

index.js

const IdleTimer = ({ timeout, onTimeout, onExpired }) => {
  const expiredTime = parseInt(localStorage.getItem('_expiredTime'), 10)
  if (expiredTime > 0 && expiredTime < Date.now()) {
    onExpired()
    return
  }
  let timeoutTracker = null

  const interval = () => {
    setInterval(() => {
      if (expiredTime < Date.now()) {
        if (onTimeout) {
          onTimeout()
          cleanUp()
        }
      }
    }, 1000)
  }

  const updateExpiredTime = (e) => {
    if (timeoutTracker) {
      clearTimeout(timeoutTracker)
    }
    timeoutTracker = setTimeout(() => {
      localStorage.setItem('_expiredTime', Date.now() + timeout * 1000)
    }, 300)
  }

  const startInterval = () => {
    updateExpiredTime()
    interval()
  }

  const tracker = () => {
    window.addEventListener('mousemove', updateExpiredTime)
    window.addEventListener('scroll', updateExpiredTime)
    window.addEventListener('keydown', updateExpiredTime)
  }

  tracker()
  startInterval()

  const cleanUp = () => {
    localStorage.removeItem('_expiredTime')
    clearInterval(interval)
    window.removeEventListener('mousemove', updateExpiredTime)
    window.removeEventListener('scroll', updateExpiredTime)
    window.removeEventListener('keydown', updateExpiredTime)
  }
}
export default IdleTimer

app.js,

const [isTimeout, setIsTimeout] = useState(false)

useEffect(() => {
  const timer = IdleTimer({
    timeout: 20, //expire after 20 seconds
    onTimeout: () => {
      setIsTimeout(true)
    },
    onExpired: () => {
      setIsTimeout(true)
    },
  })

  return () => {
    timer.cleanUp()
  }
}, [])

if (isAuthenticated && isTimeout) {
  logout()
}

请帮我解决这个问题。我想要没有 useEffect().

的功能组件

使用您在下方发送的来自 codesandbox 的 App 功能按预期工作。

const IdleTimerFun = ({ timeout, onTimeout, onExpired }) => {
  let timeoutTracker = null;
  let interval = null;

  const expiredTime = parseInt(localStorage.getItem("_expiredTime"), 10);
  if (expiredTime > 0 && expiredTime < Date.now()) {
    onExpired();
    return;
  }

  const startInterval = () => {
    updateExpiredTime();

    interval = setInterval(() => {
      const expiredTime = parseInt(localStorage.getItem("_expiredTime"), 10);
      if (expiredTime < Date.now()) {
        if (onTimeout) {
          onTimeout();
          cleanUp();
        }
      }
    }, 1000);
  };

  const updateExpiredTime = () => {
    if (timeoutTracker) {
      clearTimeout(timeoutTracker);
    }
    timeoutTracker = setTimeout(() => {
      localStorage.setItem("_expiredTime", Date.now() + timeout * 1000);
    }, 300);
  };

  const tracker = () => {
    window.addEventListener("mousemove", updateExpiredTime);
    window.addEventListener("scroll", updateExpiredTime);
    window.addEventListener("keydown", updateExpiredTime);
  };

  const cleanUp = () => {
    localStorage.removeItem("_expiredTime");
    clearInterval(interval);
    window.removeEventListener("mousemove", updateExpiredTime);
    window.removeEventListener("scroll", updateExpiredTime);
    window.removeEventListener("keydown", updateExpiredTime);
  };

  tracker();
  startInterval();
};

export default IdleTimerFun;