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

React Native中'seconds is read-only'错误的问题排查

错误原因与修复方案:"seconds" is read-only

错误根源

错误出现在useEffect中的这行代码:

setInterval(() => setSeconds(++seconds), 1000)

seconds是React useState返回的只读状态变量,++seconds等价于直接执行seconds = seconds + 1,这违反了React状态不可直接修改的规则,因此抛出"seconds is read-only"错误。

修复步骤

  1. 修正状态更新方式
    使用React状态的函数式更新,它能获取到最新的状态值,避免闭包导致的状态 stale 问题:

    setSeconds(prevSeconds => prevSeconds + 1)
    
  2. 重构重置逻辑
    原代码用全局变量startValue实现重置的方式不可靠,全局变量变化不会触发组件重新渲染。直接在组件内部通过setSeconds重置状态即可。

  3. 修正组件返回值
    原组件返回的是函数formatedTime,React组件必须返回可渲染内容(JSX、字符串等),需改为调用函数返回格式化后的时间。

完整修正代码

import { useEffect, useState } from 'react'

export const NewTimer = () => {
  const [seconds, setSeconds] = useState(0)

  const formattedTime = () => {
    return [pad(parseInt(seconds / 60)), pad(seconds % 60)].join(':')
  }

  useEffect(() => {
    const timer = setInterval(() => {
      // 函数式更新获取最新状态
      setSeconds(prevSeconds => prevSeconds + 1)
    }, 1000)
    // 组件卸载时清除定时器
    return () => clearInterval(timer)
  }, [])

  // 内部实现重置逻辑
  const resetTimer = () => {
    setSeconds(0)
  }

  // 返回可渲染的格式化时间
  return <span>{formattedTime()}</span>
}

const pad = (num) => {
  return num.toString().length > 1 ? num : `0${num}`
}

额外说明

  • 若需要在组件外部触发重置,可以通过useImperativeHandle暴露重置方法,或者将状态提升到父组件,通过props传递重置逻辑。
  • 定时器的依赖数组为空,确保只在组件挂载时启动一次定时器,卸载时清除,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Carlos del Río Francés

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 07:25:22