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

React中使用LocalStorage控制Apple设备模态框不重复弹出报错问询

问题原因

你触发报错的核心原因是在组件的顶层渲染逻辑中直接调用了setOpen这个状态更新方法:
React组件每次状态更新都会触发重新渲染,你取消注释setOpen(false)后,执行逻辑就变成:组件渲染 → 调用setOpen更新状态 → 触发重新渲染 → 再次走到判断逻辑调用setOpen,陷入无限重渲染的死循环,最终触发报错。

修复方案

按照以下逻辑调整代码即可完全匹配需求:

  1. 初始化open状态时直接从localStorage读取标记值,不需要额外在渲染过程中更新状态
  2. 把localStorage的写操作放到用户关闭Modal的回调函数中,确保只有用户主动关闭后才会标记为不再弹出
  3. 删掉原来顶层直接操作状态和localStorage的冗余逻辑

修复后完整代码

const MasterIndexPage = () => {
  const classes = useStyles()

  const [isAndroid, setIsAndroid] = useState(false)
  const [isApple, setIsApple] = useState(false)
  // 初始化时直接从localStorage判断是否要弹出:没标记过就弹出,标记过就不弹出
  const [open, setOpen] = useState(() => {
    return localStorage.getItem('formModal') === null
  })

  const handleClose = () => {
    setOpen(false)
    // 用户关闭时写入localStorage标记,后续不再弹出
    localStorage.setItem('formModal', '1')
  }

  useEffect(() => {
    if (navigator.userAgent.match(/Android/i)) {
      setIsAndroid(true)
    } else if (navigator.userAgent.match(/iPhone|iPod|iPad/i)) {
      setIsApple(true)
    }
  }, [])

  return (
    <>
      <h1>Hello</h1>
      <div>
        {isApple ? (
          <Modal
            aria-labelledby="transition-modal-title"
            aria-describedby="transition-modal-description"
            className={classes.modal}
            open={open}
            onClose={handleClose}
            closeAfterTransition
            BackdropComponent={Backdrop}
            BackdropProps={{
              timeout: 500,
            }}
          >
            <div id="popup">
              <h4 className="h4_addtohome">Add my App!</h4>
              <p className="p__addtohome">
                Tap below to add an icon to your home screen for quick access!
              </p>
            </div>
          </Modal>
        ) : null}
      </div>
    </>
  )
}

export default MasterIndexPage

额外优化说明

  • 原代码中return返回的多个根节点没有包裹,上面的代码用React Fragment(<>)做了包裹,避免语法报错
  • 去掉了无用的userAgent、isWindows状态声明,减少冗余代码
  • localStorage存储的值统一用字符串类型,避免类型判断错误

内容的提问来源于stack exchange,提问作者Pinky Promise

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:27:03