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

react-secure-storage为何有时返回null?本地存储数据明明存在

偶现页面刷新时secureLocalStorage读取返回null的解决方案

你遇到的问题核心是:页面刷新时,react-secure-storage读取userData偶发返回null,但浏览器存储中实际存在数据。这通常是组件初始化时机早于加密存储的解密完成,或是存储读取/解析过程中出现隐性错误导致的,以下是针对性解决办法:

1. 用React状态+异步读取替代同步读取

直接在组件顶层同步读取存储,可能赶不上react-secure-storage的解密初始化流程(尤其是页面刷新时)。改用useEffect异步读取,并添加加载状态避免误判:

import secureLocalStorage from 'react-secure-storage'
import { useState, useEffect } from 'react'
import { Navigate } from 'react-router-dom'

const PrivateRoute = ({ children, route }) => {
  const ability = useContext(AbilityContext)
  const [user, setUser] = useState(null)
  const [isLoading, setIsLoading] = useState(true)

  useEffect(() => {
    const loadUser = () => {
      try {
        const storedUser = secureLocalStorage.getItem('userData')
        // 先判断存储值是否存在,再解析
        if (storedUser) {
          setUser(JSON.parse(storedUser))
        }
      } catch (err) {
        console.error('读取用户数据出错:', err)
        // 解析失败时清空无效存储,避免反复报错
        secureLocalStorage.removeItem('userData')
      } finally {
        setIsLoading(false)
      }
    }

    loadUser()
  }, [])

  // 加载中显示过渡组件,不要直接跳登录
  if (isLoading) {
    return <div>加载中...</div>
  }

  if (!user) {
    console.log("跳转至登录页")
    console.log(secureLocalStorage.getItem('userData'))
    console.log(user)
    return <Navigate to='/login' />
  }

  return children
}

2. 改用Firebase Auth内置状态监听(更可靠)

既然使用Firebase Google Auth,完全可以利用Firebase自带的状态监听来处理登录校验,它会自动处理页面刷新后的状态恢复,比手动读存储更稳定:

import { getAuth, onAuthStateChanged } from "firebase/auth"
import { useState, useEffect } from 'react'
import { Navigate } from 'react-router-dom'

const PrivateRoute = ({ children, route }) => {
  const ability = useContext(AbilityContext)
  const [user, setUser] = useState(null)
  const [isLoading, setIsLoading] = useState(true)

  useEffect(() => {
    const auth = getAuth()
    // 监听Auth状态变化
    const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
      if (firebaseUser) {
        // 可选:将Firebase用户数据同步到secure local storage
        secureLocalStorage.setItem('userData', JSON.stringify(firebaseUser))
        setUser(firebaseUser)
      } else {
        setUser(null)
        secureLocalStorage.removeItem('userData')
      }
      setIsLoading(false)
    })

    // 组件卸载时取消监听,避免内存泄漏
    return unsubscribe
  }, [])

  if (isLoading) {
    return <div>加载中...</div>
  }

  if (!user) {
    return <Navigate to='/login' />
  }

  return children
}

3. 排查react-secure-storage的解密问题

  • 确认你使用的react-secure-storage版本是否有已知的初始化bug,尝试升级到最新版。
  • 该库依赖浏览器Web Crypto API,部分浏览器环境下页面刷新时API初始化可能延迟,可尝试在读取前加一个极短的延迟(仅作为临时方案):
    useEffect(() => {
      setTimeout(() => {
        const storedUser = secureLocalStorage.getItem('userData')
        // 后续处理逻辑
      }, 100)
    }, [])
    

4. 校验存储数据的完整性

偶尔的null可能是存储数据被意外损坏导致的,在读取时增加错误捕获和校验:

const storedUser = secureLocalStorage.getItem('userData')
if (storedUser) {
  try {
    const parsedUser = JSON.parse(storedUser)
    // 校验必要字段是否存在
    if (parsedUser.uid) {
      setUser(parsedUser)
    } else {
      secureLocalStorage.removeItem('userData')
    }
  } catch (err) {
    console.error('解析用户数据失败:', err)
    secureLocalStorage.removeItem('userData')
  }
}

内容的提问来源于stack exchange,提问作者Shahzad Qasir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:01:47