Next.js 使用 SSR 的本地存储问题

2024-05-06

我有以下自定义挂钩,它将数据存储在本地存储中:

import { useCallback, useEffect, useState } from "react";

export const useLocalStorage = (key, initialValue) => {
  const initialize = (key) => {
    try {
      const item = localStorage.getItem(key);
      if (item && item !== "undefined") {
        return JSON.parse(item);
      }

      localStorage.setItem(key, JSON.stringify(initialValue));
      return initialValue;
    } catch {
      return initialValue;
    }
  };

  const [state, setState] = useState(() => initialize(key)); // problem is here

  const setValue = useCallback(
    (value) => {
      try {
        const valueToStore = value instanceof Function ? value(storedValue) : value;
        setState(valueToStore);
        localStorage.setItem(key, JSON.stringify(valueToStore));
      } catch (error) {
        console.log(error);
      }
    },
    [key, setState]
  );

  const remove = useCallback(() => {
    try {
      localStorage.removeItem(key);
    } catch {
      console.log(error);
    }
  }, [key]);

  return [state, setValue, remove];
};


它显示了以下问题,我用谷歌搜索了它,似乎是由于 Nextjs 尝试在服务器端运行代码并且没有可用的窗口对象所致。

问题似乎来自我尝试初始化存储数据的行:

const [state, setState] = useState(() => initialize(key));

我尝试将此逻辑打包在 useEffect 中,以便它仅在客户端运行,但我遇到了无法解决的无限循环。


import { useCallback, useEffect, useState } from "react";

export const useLocalStorage = (key, initialValue) => {
  const initialize = (key) => {
    try {
      const item = localStorage.getItem(key);
      if (item && item !== "undefined") {
        return JSON.parse(item);
      }

      localStorage.setItem(key, JSON.stringify(initialValue));
      return initialValue;
    } catch {
      return initialValue;
    }
  };

  const [state, setState] = useState(null); // problem is here

  // solution is here....
  useEffect(()=>{
    setState(initialize(key));
  },[]);

  const setValue = useCallback(
    (value) => {
      try {
        const valueToStore = value instanceof Function ? value(storedValue) : value;
        setState(valueToStore);
        localStorage.setItem(key, JSON.stringify(valueToStore));
      } catch (error) {
        console.log(error);
      }
    },
    [key, setState]
  );

  const remove = useCallback(() => {
    try {
      localStorage.removeItem(key);
    } catch {
      console.log(error);
    }
  }, [key]);

  return [state, setValue, remove];
};

window,localStorage,sessionStorage,etc..未在服务器上定义,因此在服务器上访问它们将导致错误。使用useEffect为了确保这一点,这些代码将在客户端执行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Next.js 使用 SSR 的本地存储问题 的相关文章

  • React.js:可以在函数组件之外分配 useState() 吗?

    是否有任何语法允许分配useState在功能组件之外 到目前为止我已经尝试过 但没有成功 import React useState useEffect from react import ReactDOM from react dom f
  • React router v6 和路由内页面的相关链接

    您好 我正在尝试使用 React Router 将项目更新到 v6 我了解了基础知识 但在相关链接方面遇到了困难 我们有一个页面 通过 id 呈现给定项目的参考文档 该文档可以使用同级 ID 链接到其他 同级 材料 换句话说 用户可以在文档
  • Jest - 模拟函数,从另一个文件导入

    测试的文件使用从另一个文件导入的函数 import myFunc from myFile 如何在该文件的测试中模拟该函数的返回值 我正在使用笑话 这对我有用 我不确定这是否是一个好的做法 import as myFile from myFi
  • 如何在react-三纤维中提取并播放动画

    嗯 我有 gltf 动画模型 我成功加载模型 但无法播放嵌入的动画 我想知道是否可以以任何方式解决它 顺便说一句 我正在反应中工作 先感谢您 在这里您可以找到型号https drive google com file d 1ZVyklaQu
  • 如何判断何时创建新组件?

    我一直在寻找背后的逻辑当有人在 AngularJS Angular 上的 Web 应用程序中创建新组件时但我认为这更通用 可能适用于所有基于组件的前端框架 我知道有像这样的一些原则应该是抽象的和可重用的但例如我在角度文档中看到 每个单独的路
  • 以编程方式更改 Redux-Form 字段值

    当我使用redux formv7 我发现没有办法设置字段值 现在在我的form 我有两个select成分 当第一个时 第二个的值就会很清楚select元件值改变 在类渲染中 div div site div div div div
  • 如何在 Gatsby 页面上包含本地 JavaScript?

    我是一个完全的 React 新手 我想这里有些基本的东西我不太明白 默认的 Gatsby 页面如下所示 有没有办法像这样使用本地 js 文件 我想要实现的是让反应忽略script js但仍然让客户端使用它 默认的 Gatsby 页面看起来像
  • ReactJS 子级 - 过滤掉空值

    我正在渲染我的组件
  • NextjS src 和默认外部图像 URL 的图像问题

    我正在使用最新版本的 NextJS 10 0 9 我有一个想要显示的图像 但是收到错误 Error Image with src https picsum photos 480 270 must use width and height p
  • 带换行符的 React/Momentjs 日期格式

    我有一个日期字符串 我想对其进行格式化 其中数字位于月份下 Jul 6 我尝试了几种不同的方法来添加新行
  • React JS 服务器端问题 - 找不到窗口

    你好 我正在尝试在我的reactJS项目中使用react rte 我有服务器端渲染 每次我想使用这个包时 我都会得到 return msie 6 9 b test window navigator userAgent toLowerCase
  • 如何映射轮播的子项数组?

    我正在尝试将 Carousel 组件包装在映射对象数组周围作为组件的子级 目前我只能让映射创建映射对象的 1 个子对象 轮播需要像这样
  • 使用 Reactjs 获取滚动位置

    我使用reactjs并想要处理滚动click event 首先 我呈现了帖子列表componentDidMount 其次 通过click event在列表中的每个帖子上 它将显示帖子详细信息并滚动到顶部 因为我将帖子详细信息放在页面的顶部位
  • 在react-big-calendar中单击事件时添加弹出窗口?

    当单击事件时 我无法将弹出窗口添加到事件中 弹出窗口似乎只显示在事件槽中 而不是显示在事件槽的顶部 此外 由于我为事件创建了一个自定义组件并尝试在自定义组件中实现弹出窗口 因此只有当我单击事件名称时才会显示弹出窗口 这是代码 class C
  • 在 onChange 事件中调用 2 个函数

    我对我的组件有点困惑 我需要从 props 调用 onChange 所以
  • 在旧浏览器上使用 Fetch 的 ReactJS

    我正在使用 Webpack 和 Babel 实现 React JS 但是 我在让 Fetch 与 IE 11 配合使用时遇到问题 我的 babelrc 文件中有以下内容 presets env stage 0 react 以及我的 webp
  • React 在同一组件中渲染多个模态

    我对 React 和一般编码都很陌生 我试图在同一组件中渲染多个模态 但它们都是同时渲染的 因此看起来所有链接都在最后一个模态中渲染文本 这是状态设置的地方 class Header extends React Component cons
  • ReactJS - Redux Form - 如何根据单选字段元素有条件地显示/隐藏元素?

    我对 Redux 比较陌生 我有一个表单 其中有一些无线电输入 是 或 否 基本上 我想根据该无线电输入选择有条件地显示包含另一个 redux 表单字段的另一个元素 有直接的方法可以做到这一点吗 我想检查一下formProps site v
  • ReactCSSTransitionGroup 组件WillLeave 未调用

    我尝试使用 ReactCssTransition 但不知何故该事件没有被调用 componentWillLeave 这是我的组件 import React Component from react import TransitionGrou
  • p5 向量减法“sub”返回错误

    我一直在尝试将 p5 草图上传到 React 构建中 使用react p5 wrapper 我能够成功在屏幕上渲染画布 但是 某些矢量函数会导致错误 var distance this position dist ball position

随机推荐