You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件实现退出暂停计时器、登录恢复计时及登录页显示剩余时间的问题求助

React组件实现退出暂停计时器、登录恢复计时及登录页显示剩余时间的问题求助

看起来你现在遇到了三个核心问题:点击Exit按钮时计时器停不下来、登录后没法从暂停的时间继续计时,还有登录页面没法正确显示剩余时间。我来帮你逐个解决这些问题:

问题根源梳理

  1. 计时器引用丢失:你在LabPart里用普通变量interval保存定时器,组件每次渲染都会重置这个变量,导致handleExitClick里的clearInterval找不到正确的定时器引用。
  2. 状态未持久化:组件卸载后内部状态会丢失,退出时的剩余时间没保存,登录后自然没法恢复。
  3. 登录页传参逻辑混乱:原代码里的newTimeRemaining和未定义的x变量导致剩余时间无法正确展示。

完整修复代码

1. 修改LabPart.jsx

import React, { useState, useEffect, useRef } from 'react';
import Login from './Login';

const LabPart = ({ initialTime, password }) => {
  const [pass, setPass] = useState(password);
  // 优先从本地存储读取剩余时间,无值则用传入的初始时间
  const [timeRemaining, setTimeRemaining] = useState(() => {
    const savedTime = localStorage.getItem('remainingTime');
    return savedTime ? parseInt(savedTime) : initialTime;
  });
  // 用useRef持久化定时器引用,避免渲染重置
  const intervalRef = useRef(null);

  useEffect(() => {
    // 仅当用户登录且时间有效时启动定时器
    if (pass && timeRemaining >= 0) {
      intervalRef.current = setInterval(() => {
        setTimeRemaining(prevTime => {
          const newTime = prevTime - 1;
          // 每次更新时间都同步到本地存储
          localStorage.setItem('remainingTime', newTime.toString());
          return newTime;
        });
      }, 1000);
    }
    // 组件卸载或依赖变化时清除定时器
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, [pass, timeRemaining]);

  const handleExitClick = () => {
    console.log("logout successful");
    // 清除定时器并清空引用
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
    }
    // 清空密码触发登录页跳转
    setPass("");
  };

  const hours = Math.floor(timeRemaining / 3600);
  const minutes = Math.floor((timeRemaining % 3600) / 60);
  const seconds = timeRemaining % 60;

  return (
    <>
      {pass && timeRemaining >= 0 ? (
        <div>
          <p>Time remaining: {hours}h {minutes}m {seconds}s</p>
          <button onClick={handleExitClick}>Exit</button>
        </div>
      ) : (
        <Login />
      )}
    </>
  )
}

export default LabPart;

2. 修改Login.jsx

import React, { useState } from "react";
import LabPart from "./LabPart";
import '../style/login.css';

const Login = () => {
  const [password, setPassword] = useState("");
  const [openPage, setOpenPage] = useState(false);
  // 从本地存储读取剩余时间,无值则用默认10秒
  const remainingTime = parseInt(localStorage.getItem('remainingTime')) || 10;

  const handlePasswordChange = (event) => {
    setPassword(event.target.value);
  };

  const handleFormSubmit = (event) => {
    event.preventDefault();
    if (password === "12345") {
      console.log("login successful");
      setOpenPage(true);
    } else {
      alert("Incorrect Password")
    }
  };

  const hours = Math.floor(remainingTime / 3600);
  const minutes = Math.floor((remainingTime % 3600) / 60);
  const seconds = remainingTime % 60;

  return (
    <>
      {openPage ? (
        <LabPart initialTime={remainingTime} password={password} />
      ) : (
        <form onSubmit={handleFormSubmit}>
          <input
            type="password"
            value={password}
            onChange={handlePasswordChange}
            placeholder="Enter password"
          />
          <button type="submit">Enter</button>
          {/* 展示剩余时间 */}
          <p>Remaining Time: {hours}h {minutes}m {seconds}s</p>
        </form>
      )}
    </>
  );
};

export default Login;

关键修改说明

  • useRef保存定时器:解决了clearInterval无效的问题,useRef的.current属性在组件生命周期内保持引用不变。
  • localStorage持久化时间:退出时的剩余时间会存在本地,登录后直接读取,确保状态不会丢失。
  • 简化传参逻辑:去掉冗余的props,直接从本地存储读取数据,逻辑更清晰。
  • 优化定时器启动条件:只有用户登录且时间有效时才启动定时器,避免无效运行。

这样修改后,点击Exit按钮时定时器会被正确清除,登录页面能显示剩余时间,登录后也会从暂停的时间继续计时啦。

备注:内容来源于stack exchange,提问作者torq1284

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 08:44:13