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

添加'use client'后仍遇ReferenceError: localStorage未定义问题求助

问题解决:Next.js 13.4.1 中 localStorage is not defined 报错

错误原因

你已经给组件加了'use client',但Next.js App Router的客户端组件在服务端渲染阶段依然会执行组件的初始化代码(包括useState的初始值计算、变量声明)。而localStorage是浏览器专属的API,服务端环境中不存在,所以直接在组件顶层或useState初始值里调用localStorage.getItem会触发报错。

修复方案

有两种可靠的修复方式,核心都是确保localStorage的访问只在客户端环境执行:

方式1:使用useState的函数式初始值

利用函数式初始值只会在客户端执行的特性,先判断环境再读取本地存储:

'use client';
import { useState } from 'react';

const Cookies = () => {
  // 用函数式初始值,确保仅在客户端访问localStorage
  const [cookiesAccepted, setCookiesStatus] = useState<boolean>(() => {
    if (typeof localStorage !== 'undefined') {
      return !!localStorage.getItem('cookies-accepted');
    }
    return false;
  });

  const acceptCookies = () => {
    localStorage.setItem('cookies-accepted', 'true');
    setCookiesStatus(true);
  }
  
  return (
    <>
      {!cookiesAccepted && (
        <section className="fixed max-w-md p-4 mx-auto bg-white border border-gray-200 left-12 bottom-16  rounded-2xl z-20">
          <h2 className="font-semibold text-gray-800 ">🍪 Cookie Notice</h2>

          <p className="mt-4 text-sm text-gray-600">
            We use cookies to ensure that we give you the best experience on our
            website.{' '}
            <a href="#" className="text-blue-500 hover:underline">
              Read cookies policies
            </a>
            .{' '}
          </p>

          <div className="flex items-center justify-between mt-4 gap-x-4 shrink-0">
            <button className="text-xs text-gray-800 underline transition-colors duration-300 hover:text-gray-600 focus:outline-none">
              Manage your preferences
            </button>

            <button
              className=" text-xs bg-gray-900 font-medium rounded-lg hover:bg-gray-700 text-white px-4 py-2.5 duration-300 transition-colors focus:outline-none"
              onClick={acceptCookies}
            >
              Accept
            </button>
          </div>
        </section>
      )}
    </>
  );
};

export default Cookies;

方式2:使用useEffect延迟读取本地存储

useEffect的回调函数只会在客户端组件挂载后执行,服务端不会运行这部分代码:

'use client';
import { useState, useEffect } from 'react';

const Cookies = () => {
  const [cookiesAccepted, setCookiesStatus] = useState<boolean>(false);

  useEffect(() => {
    // 组件挂载后再读取localStorage
    const storedCookies = localStorage.getItem('cookies-accepted');
    setCookiesStatus(!!storedCookies);
  }, []);

  const acceptCookies = () => {
    localStorage.setItem('cookies-accepted', 'true');
    setCookiesStatus(true);
  }
  
  return (
    <>
      {!cookiesAccepted && (
        <section className="fixed max-w-md p-4 mx-auto bg-white border border-gray-200 left-12 bottom-16  rounded-2xl z-20">
          <h2 className="font-semibold text-gray-800 ">🍪 Cookie Notice</h2>

          <p className="mt-4 text-sm text-gray-600">
            We use cookies to ensure that we give you the best experience on our
            website.{' '}
            <a href="#" className="text-blue-500 hover:underline">
              Read cookies policies
            </a>
            .{' '}
          </p>

          <div className="flex items-center justify-between mt-4 gap-x-4 shrink-0">
            <button className="text-xs text-gray-800 underline transition-colors duration-300 hover:text-gray-600 focus:outline-none">
              Manage your preferences
            </button>

            <button
              className=" text-xs bg-gray-900 font-medium rounded-lg hover:bg-gray-700 text-white px-4 py-2.5 duration-300 transition-colors focus:outline-none"
              onClick={acceptCookies}
            >
              Accept
            </button>
          </div>
        </section>
      )}
    </>
  );
};

export default Cookies;

补充说明

把组件移到app文件夹外没用,因为App Router中,只要组件被导入到服务端渲染的页面(比如app/page.tsx默认是服务端组件),客户端组件的初始化代码依然会在服务端被执行一次,直到完成hydration后才完全在客户端运行。所以关键是避免在服务端执行的代码块中访问浏览器专属API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:10:23