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

使用ReactJS开发秒表后如何实现浏览器刷新时计时数据不丢失

React秒表刷新保留计时数值的实现方案

要实现浏览器刷新后秒表计时不重置,本质是将秒表的核心运行状态持久化存储在浏览器本地,页面重新加载时优先读取本地存储的状态完成初始化即可。

实现步骤

  • 第一步:确定需要持久化的核心状态
    一共需要存储3个关键字段,避免刷新后逻辑出错:
    • 累计计时毫秒数:不要存储格式化后的字符串,避免后续转换误差
    • 秒表运行状态:标记当前是运行中/暂停/已重置状态
    • 最后一次状态更新的时间戳:用于计算刷新期间流逝的时间,保证运行中的秒表刷新后可以自动补全计时
  • 第二步:状态变更时同步到本地存储
    每次计时更新、运行状态切换时,都将最新状态同步写入localStorage,示例方法:
    const saveState = (currentState) => {
      localStorage.setItem('stopwatch_data', JSON.stringify({
        ...currentState,
        lastUpdateTime: Date.now()
      }))
    }
    
  • 第三步:页面初始化时读取本地存储的状态
    组件挂载时优先读取localStorage中的秒表数据,如果是运行中状态,需要先计算刷新期间流失的时间,补到累计计时值后再启动计时器:
    useEffect(() => {
      const savedData = localStorage.getItem('stopwatch_data')
      if (!savedData) return
      const { totalTime, isRunning, lastUpdateTime } = JSON.parse(savedData)
      if (isRunning) {
        // 补算刷新期间的时间差
        const offset = Date.now() - lastUpdateTime
        setTotalTime(totalTime + offset)
        setIsRunning(true)
      } else {
        setTotalTime(totalTime)
      }
    }, [])
    
  • 第四步:适配重置逻辑
    用户点击重置秒表时,除了清空本地state,还要同步删除localStorage中存储的秒表数据,避免下次打开页面加载旧数据。

完整代码示例

import { useState, useEffect, useRef } from 'react'

function Stopwatch() {
  const [totalTime, setTotalTime] = useState(0)
  const [isRunning, setIsRunning] = useState(false)
  const timerRef = useRef(null)

  // 初始化加载本地存储状态
  useEffect(() => {
    const savedData = localStorage.getItem('stopwatch_data')
    if (!savedData) return
    const { totalTime: savedTime, isRunning: savedRunning, lastUpdateTime } = JSON.parse(savedData)
    if (savedRunning) {
      const offset = Date.now() - lastUpdateTime
      setTotalTime(savedTime + offset)
      setIsRunning(true)
    } else {
      setTotalTime(savedTime)
    }
  }, [])

  // 状态变更同步到本地存储
  useEffect(() => {
    if (isRunning || totalTime > 0) {
      localStorage.setItem('stopwatch_data', JSON.stringify({
        totalTime,
        isRunning,
        lastUpdateTime: Date.now()
      }))
    }
  }, [totalTime, isRunning])

  // 计时器运行逻辑
  useEffect(() => {
    if (isRunning) {
      timerRef.current = setInterval(() => {
        setTotalTime(prev => prev + 10)
      }, 10)
    } else {
      clearInterval(timerRef.current)
    }
    return () => clearInterval(timerRef.current)
  }, [isRunning])

  // 操作方法
  const handleStart = () => setIsRunning(true)
  const handlePause = () => setIsRunning(false)
  const handleReset = () => {
    setIsRunning(false)
    setTotalTime(0)
    localStorage.removeItem('stopwatch_data')
  }

  // 时间格式化,原有逻辑可直接复用
  const formatTime = (ms) => {
    const seconds = Math.floor(ms / 1000) % 60
    const minutes = Math.floor(ms / 60000) % 60
    const hours = Math.floor(ms / 3600000)
    return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
  }

  return (
    <div className="stopwatch">
      <h2>{formatTime(totalTime)}</h2>
      <button onClick={handleStart} disabled={isRunning}>启动</button>
      <button onClick={handlePause} disabled={!isRunning}>暂停</button>
      <button onClick={handleReset}>重置</button>
    </div>
  )
}

export default Stopwatch

注意事项

  • 本地存储仅支持同一浏览器同一设备的状态持久化,如果需要跨设备同步,可以把存储逻辑替换为后端接口读写
  • localStorage存储的是字符串,读写时需要做JSON序列化和反序列化处理
  • 如果使用React18严格模式,开发环境下useEffect会执行两次,属于框架正常行为,不影响生产环境运行

内容的提问来源于stack exchange,提问作者Aswin.S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:09:02