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

Next.js 14中useLocalStorage客户端钩子报错问题求助

解决Next.js 14中useLocalStorage钩子的"client-only hook"报错问题

以下是几个可行的解决方法,按优先级尝试:

1. 确保"use client"指令是文件第一行

检查你的HomePage.tsx文件,确保"use client";是文件的第一行代码,前面不能有任何注释、空格或其他导入语句。示例:

"use client";
import { useLocalStorage } from "@uidotdev/usehooks";
// 其他导入和代码...

Next.js对这个指令的位置要求严格,位置偏移会导致指令不生效。

2. 更新@uidotdev/usehooks到最新版本

部分旧版本的该库在Next.js 14的App Router下存在兼容性问题,执行以下命令更新依赖:

npm update @uidotdev/usehooks
# 或使用yarn
yarn upgrade @uidotdev/usehooks

更新后重启开发服务器,再测试是否解决问题。

3. 将useLocalStorage封装到独立的Client组件

如果直接在HomePage使用仍有问题,可以把计数器逻辑封装到一个单独的带"use client"的组件中:

创建Counter.tsx文件:

"use client";
import { useLocalStorage } from "@uidotdev/usehooks";
import { Button } from "./ui/button";

export default function Counter() {
  const [count, setCount] = useLocalStorage("count", 0);

  return (
    <>
      <header className="...">Count: {count}</header>
      <div className="...">
        <Button onClick={() => setCount((prev) => prev + 1)}>Increment</Button>
        <Button onClick={() => setCount((prev) => prev - 1)}>Decrement</Button>
        <Button onClick={() => setCount(0)}>Reset</Button>
      </div>
    </>
  );
}

然后在HomePage.tsx中导入使用:

import Counter from "./Counter";
import { Separator } from "./ui/separator";

const HomePage = () => {
  return (
    <div className="...">
      <header className="...">Home Page</header>
      <Separator />
      <Counter />
    </div>
  );
};

export default HomePage;

这种方式能确保钩子只在纯Client组件中执行,避免Server端渲染时的冲突。

4. 手动实现适配Next.js 14的useLocalStorage钩子

如果以上方法都无效,可以自己写一个简易版本的useLocalStorage,适配Next.js的Client组件:

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

export function useLocalStorage<T>(key: string, initialValue: T) {
  // 初始化状态:优先从localStorage取,没有则用初始值
  const [storedValue, setStoredValue] = useState<T>(() => {
    if (typeof window === "undefined") {
      return initialValue;
    }
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });

  // 更新localStorage当状态改变时
  useEffect(() => {
    try {
      const valueToStore = typeof storedValue === "string" ? storedValue : JSON.stringify(storedValue);
      window.localStorage.setItem(key, valueToStore);
    } catch (error) {
      console.error(error);
    }
  }, [key, storedValue]);

  return [storedValue, setStoredValue] as const;
}

然后在你的组件中导入这个自定义钩子即可使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:32:12