如何将下述JavaScript localStorage操作代码改写为ReactJS实现
原生localStorage代码的React适配实现
React在浏览器环境下完全兼容原生localStorage API,不需要额外引入第三方依赖,只需要把存储逻辑放到符合React执行规范的位置即可,服务端渲染场景额外做环境判断就不会报错。
基础写法(纯客户端React SPA场景)
你原来写的localStorage操作核心逻辑完全不需要修改,只要不要直接在函数组件的渲染主流程里调用,放到事件回调、useEffect副作用这类非即时渲染执行的位置即可,比如登录接口请求成功的回调里直接复用:
// 接口请求成功后的回调函数中直接使用 const fetchLogin = async (loginParams) => { const response = await axios.post('/api/auth/login', loginParams) // 原有存储逻辑直接复用 localStorage.setItem("actNumber", JSON.stringify(response.data.accountNumbers)) localStorage.setItem("Token", response.data.accessToken) localStorage.setItem("cifNumber", JSON.stringify(response.data.cifNumber).replace(/^"(.*)"$/, '$1')) // 后续路由跳转、全局状态更新逻辑 }
- 禁止直接在函数组件return前的渲染流程里写localStorage操作,会导致重复执行、渲染不一致问题。
- 类组件场景下,可以把这类逻辑放到
componentDidMount、componentDidUpdate生命周期或者事件回调中。
SSR框架适配写法(Next.js/Remix等)
服务端渲染阶段不存在window/localStorage对象,直接调用会抛出引用错误,最稳妥的方式是把存储逻辑放到useEffect回调中——useEffect的代码只会在客户端执行,天然避开SSR环境问题:
import { useEffect } from 'react' function AuthComponent({ response }) { useEffect(() => { if (!response?.data) return localStorage.setItem("actNumber", JSON.stringify(response.data.accountNumbers)) localStorage.setItem("Token", response.data.accessToken) localStorage.setItem("cifNumber", JSON.stringify(response.data.cifNumber).replace(/^"(.*)"$/, '$1')) }, [response]) // 组件渲染逻辑 }
可选优化:封装响应式LocalStorage Hook
如果需要让localStorage存储的值和React状态自动同步,可以封装通用自定义Hook,省去重复写setItem/getItem的逻辑:
import { useState } from 'react' function useLocalStorage(key, initialValue) { const [storedValue, setStoredValue] = useState(() => { // 兼容SSR环境 if (typeof window === 'undefined') return initialValue try { const item = window.localStorage.getItem(key) return item ? JSON.parse(item) : initialValue } catch (err) { return initialValue } }) const setValue = (value) => { const valueToStore = value instanceof Function ? value(storedValue) : value setStoredValue(valueToStore) if (typeof window === 'undefined') return // 适配不同key的存储规则,和你原逻辑保持一致 switch(key) { case 'Token': localStorage.setItem(key, valueToStore) break case 'cifNumber': localStorage.setItem(key, JSON.stringify(valueToStore).replace(/^"(.*)"$/, '$1')) break default: localStorage.setItem(key, JSON.stringify(valueToStore)) } } return [storedValue, setValue] } // 组件内使用示例 function LoginPage() { const [, setActNumber] = useLocalStorage('actNumber', []) const [, setToken] = useLocalStorage('Token', '') const [, setCifNumber] = useLocalStorage('cifNumber', '') const onLoginSuccess = (res) => { setActNumber(res.data.accountNumbers) setToken(res.data.accessToken) setCifNumber(res.data.cifNumber) // 后续跳转逻辑 } // 其余表单、渲染逻辑 }
额外提示:你原代码中对cifNumber做了JSON.stringify后去除首尾双引号的操作,如果接口返回的cifNumber本身就是字符串类型,直接存储
response.data.cifNumber即可,不需要额外做序列化+正则替换,能减少冗余代码。
内容的提问来源于stack exchange,提问作者deepika k
相关产品推荐
相关产品推荐

