解析Cookie值时出现SyntaxError及重复渲染错误的原因咨询
我已成功设置Cookie,执行console.log(getCookie('key'))时能看到如下内容:
[{"pic":"https://something.jpg","des":"something","price":"something","score":"something","id":0,"explink":"something"}]
但执行JSON.parse(getCookie('key'))时出现错误:
SyntaxError: Unexpected token u in JSON at position 0
我使用的代码如下:
import Layout from '../components/layout'; import { useState, createContext, useEffect } from 'react'; import AppContext from '../components/AppContext'; import '../styles/globals.css'; import { getCookies, getCookie, setCookie, deleteCookie } from 'cookies-next'; export default function MyApp({ Component, pageProps }) { const [count, setcount] = useState(0); const [card, setcard] = useState([]); setCookie('key', JSON.stringify(card)); setcard(JSON.parse(getCookie('key'))); return ( <div> <AppContext.Provider value={{ count, setcount, card, setcard, }} > <Layout> <Component {...pageProps} /> </Layout> </AppContext.Provider> </div> ); }
请问出现该错误的原因是什么?
我还尝试了setcard(getCookie('key'));,但出现以下错误:
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
This error happened while generating the page. Any console logs will be displayed in the terminal window.
1. JSON解析错误的原因
这个错误本质是JSON.parse接收到了undefined值。因为你直接在组件函数体里调用setCookie和setcard,Cookie的读写是异步操作,无法保证写入后立刻就能读取到最新值,此时getCookie('key')可能返回undefined,对undefined执行JSON.parse就会抛出该错误。另外,初始时card是空数组,直接将其转存到Cookie再读取回来的流程本身没有意义,还会触发不必要的状态更新。
2. 无限重渲染的原因
当你直接在组件函数体里调用setcard(getCookie('key'))时,每次组件渲染都会执行状态更新操作,状态更新又会触发组件重新渲染,循环往复就触发了React的无限重渲染限制报错。
正确实现方式
把Cookie的读取和设置逻辑放到useEffect钩子中,确保仅在组件挂载或指定依赖变化时执行,避免异步问题和无限循环:
import Layout from '../components/layout'; import { useState, createContext, useEffect } from 'react'; import AppContext from '../components/AppContext'; import '../styles/globals.css'; import { getCookies, getCookie, setCookie, deleteCookie } from 'cookies-next'; export default function MyApp({ Component, pageProps }) { const [count, setcount] = useState(0); const [card, setcard] = useState([]); // 组件挂载时读取Cookie数据 useEffect(() => { const savedCard = getCookie('key'); if (savedCard) { try { setcard(JSON.parse(savedCard)); } catch (err) { console.error('解析Cookie失败:', err); } } }, []); // 监听card状态变化,同步更新Cookie useEffect(() => { setCookie('key', JSON.stringify(card)); }, [card]); return ( <div> <AppContext.Provider value={{ count, setcount, card, setcard, }} > <Layout> <Component {...pageProps} /> </Layout> </AppContext.Provider> </div> ); }
这样做的优势:
- 第一个
useEffect(空依赖数组)仅在组件挂载时执行一次,避免初始渲染时的异步读取问题 - 第二个
useEffect仅在card状态变化时更新Cookie,减少不必要的Cookie写入操作 - 添加
try/catch捕获解析异常,防止解析错误导致组件崩溃
内容的提问来源于stack exchange,提问作者dads

