当我try 以以下方式在Next.js中使用https://usehooks-ts.com/react-hook/use-local-storage时,我得到

未处理的运行时错误:文本内容不匹配 服务器呈现的HTML.

请在此处查看更多信息: https://nextjs.org/docs/messages/react-hydration-error

  const [toleranceH, setToleranceH] = useLocalStorage<number>('toleranceH', 3);
  const [toleranceS, setToleranceS] = useLocalStorage<number>('toleranceS', 3);
  const [toleranceL, setToleranceL] = useLocalStorage<number>('toleranceL', 3);

  const [results, setResults] = useState<MegaColor[]>([]);

  const debouncedToleranceH = useDebounce<number>(toleranceH, 200);
  const debouncedToleranceS = useDebounce<number>(toleranceS, 200);
  const debouncedToleranceL = useDebounce<number>(toleranceL, 200);

  useEffect(() => {
    const targetColorDetailsObject = getColorDetailsObject(targetColor);
    const degreeTolerance = (360 / 100) * debouncedToleranceH;
    const [hueMin, hueMax] = getHueTolerance(targetColorDetailsObject.hue(), degreeTolerance);
    const filteredColors = getFilteredColors(targetColorDetailsObject, loadedMegaColors, hueMin, hueMax, debouncedToleranceS, debouncedToleranceL);
    setResults(filteredColors);
    return () => {
      // console.log('cleanup');
    };
  }, [targetColor, loadedMegaColors, debouncedToleranceH, debouncedToleranceS, debouncedToleranceL]); 

从那个帮助页面上,我仍然不知道该调整什么,这样我才能同时使用useLocalStorageuseDebounce.

我找到了https://stackoverflow.com/a/73411103/470749个值,但不想强制设置一个本地存储值(它应该只由用户设置).

推荐答案

我建议看看这本由Josh W Comeau compose 的关于补液的优秀post.

由于Next.js默认情况下会预先呈现每个页面,因此您需要确保调用window.localst或age的组件只在客户机上呈现.

一个简单的解决方案是:

  1. 保持hasMounted状态
const [hasMounted, setHasMounted] = useState(false);
  1. useEffect内切换
useEffect(() => {
  // This will only be called once the component is mounted inside the browser
  setHasMounted(true);
}, []);
  1. 添加复选标记,这样Next.js就不会抱怨在服务器上预先呈现的内容与客户端上呈现的内容不匹配
if (!hasMounted) {
  return null;
}
  1. 确保客户端的东西在判断后送到

要使其更具可重用性,您可以使用这两种方法中的一种,这两种方法实质上是相同的:

仅客户端组件

function ClientOnly({ children, ...delegated }) {
  const [hasMounted, setHasMounted] = React.useState(false);
  React.useEffect(() => {
    setHasMounted(true);
  }, []);
  if (!hasMounted) {
    return null;
  }
  /**
   * Could also replace the <div></div> with
   * <></> and remove ...delegated if no need
   */
  return (
    <div {...delegated}> 
      {children}
    </div>
  );
}

...

<ClientOnly>
  <MyComponent /> // <--- client only stuff, safe to use useLocalSt或age in here
</ClientOnly>

自定义使用Hasmount挂钩

function useHasMounted() {
  const [hasMounted, setHasMounted] = React.useState(false);
  React.useEffect(() => {
    setHasMounted(true);
  }, []);
  return hasMounted;
}

...

function ParentComponent() {  
  const hasMounted = useHasMounted();
  if (!hasMounted) {
    return null;
  }
  return (
    <MyComponent />
  );
}

...

function MyComponent() {
  const [toleranceH, setToleranceH] = useLocalSt或age<number>('toleranceH', 3);
  const [toleranceS, setToleranceS] = useLocalSt或age<number>('toleranceS', 3);
  const [toleranceL, setToleranceL] = useLocalSt或age<number>('toleranceL', 3);

  ...
}

...

Note:

By overdoing this 或 using this method at the top level of your component tree, you are killing the Next.js prerendering capabilities and turning your app into m或e of a "client-side heavy" app (see perf或mance implications). If you are using window.localst或age (outside of components, where you don't have useEffect available), you should always wrap with:

if (typeof window !== 'undefined') {
  // client-side code
}

Node.js相关问答推荐

在child_Process中持久运行SSH命令

如何在MEVN堆栈中结合创建和更新表单流程?

AWS-ROUTE 53指向S3存储桶,错误是别名目标名称不在目标区域内

如何从基于JSON的HTML/SCSS模板生成PDF?

为什么 Cors 在 NodeJS 中不起作用

TS[2339]:类型 '() => Promise<(Document & Omit) | 上不存在属性空>'

连接到在线 redis 数据库时出错

firebase/messaging 不提供名为 getToken 的导出

MongoDB Aggregate - 如何使用前一阶段的值作为下一阶段的字段名称?

多字段传递获取查询失败

Electron 模板(Typescript + Webpack)中的这个 Electron Forge ERROR 是什么?

表达限制资源属于特定用户的优雅方式

NestJS TypeORM 可选查询不起作用

为当前目录提供服务的简单文件服务器

Node.js 服务器中没有缓存

npm package.json 操作系统特定脚本

Express.js:没有这样的文件或目录

我可以有条件地将 where() 子句添加到我的 knex 查询吗?

Bootstrap 中的 Grunt 依赖冲突

如何在 node.js 沙箱中安全地运行用户提交的脚本?