React - 显示“localStorage 未定义”错误

Posted

技术标签:

【中文标题】React - 显示“localStorage 未定义”错误【英文标题】:React - “localStorage is not defined” error showing 【发布时间】:2019-02-27 15:54:29 【问题描述】:

我正在尝试使用元标记使我的网站 SEO 友好。 我正在我的应用程序中实现服务器端渲染。在此之后,我收到以下错误:

ReferenceError: localStorage 未定义。

请帮忙解决一下。

我的package.json




 "main": "server.js",
 "scripts": 
  "start-dev": "NODE_ENV=development webpack -w & NODE_ENV=development node server.js",
  "test": "echo \"Error: no test specified\" && exit 1"
 ,
 "keywords": [],
 "author": "",
 "license": "ISC",
 "dependencies": 
  "axios": "^0.18.0",
  "express": "^4.15.3",
  "firebase": "^4.12.1",
  "html2canvas": "^1.0.0-alpha.12",
  "react": "^16.2.0",
  "react-adsense": "0.0.5",
  "react-dom": "^16.2.0",
  "react-facebook-login": "^4.0.1",
  "react-google-login": "^3.2.1",
  "react-meta-tags": "^0.3.0",
  "react-router-dom": "^4.2.2",
  "react-router-match-as-promised": "^1.0.5",
  "react-scripts": "1.1.1",
  "react-share": "^2.1.1",
  "react-slick": "^0.22.3"
 ,
 "devDependencies": 
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.25.0",
  "babel-loader": "^7.1.1",
  "babel-preset-es2015": "^6.24.1",
  "babel-preset-react-app": "^3.1.2",
  "babel-preset-stage-0": "^6.24.1",
  "css-loader": "^0.28.4",
  "extract-text-webpack-plugin": "^2.1.2",
  "file-loader": "^0.11.2",
  "postcss-loader": "^2.0.6",
  "webpack": "^3.1.0",
  "webpack-node-externals": "^1.7.2"
 

所有页面中常用的元标记。 主页.js

<code>
import React,  Component  from 'react';
import axinst from '../common';
import TabBox,TabBox2,TabBox3 from '../common/tabbox';
import Ads  from '../common/ads';
import SubscribeFrm from '../common/subscribefrm';
import MetaTags from 'react-meta-tags';
import AdSense from 'react-adsense';
import Loader from '../common/loader';

class Home extends Component 
  constructor(props) 
    super(props);
  

  state = 
    header:[],
    otherSports:[],
    wizztalk:[],
    sports:[],
    isProgress:'',
    activeCat: '',
    metaTitle:'',
    metaDesc:'',
    metaKey:''
  

  componentDidMount()


    // axinst.get('/home')
    this.setState(isProgress:true);
    axinst.get('/home').then(response => 
      this.setState(isProgress:false);
      const header = response.data.data.Header;
      const sports = response.data.data.Sports;
      const otherSports = response.data.data.OtherSports;
      const wizztalk = response.data.data.Wizztalk;
      const metaTitle = response.data.data.metaTitle;
      const metaDesc = response.data.data.metaDesc;
      const metaKey = response.data.data.metaKeyword;
      this.setState(header);
      this.setState(sports);
      this.setState(otherSports)
      this.setState(wizztalk);
      this.setState(metaTitle);
      this.setState(metaDesc);
      this.setState(metaKey);
    ).catch(function (error) 
      // console.log(error);
      // console.log('error');
    );
  

  render() 
    const hD = this.state.header;
    const sport = this.state.sports;
    return (
    <div id="maincontent">
        <MetaTags>
          <title>this.state.metaTitle</title>
          <meta name="title" content=this.state.metaTitle />
          <meta name="keywords" content=this.state.metaKeyword />
          <meta name="description" content=this.state.metaDesc />
          <meta name="og:description" content=this.state.metaDesc />
          <meta name="og:title" content=this.state.metaTitle />
          <meta name="og:image" content=process.env.PUBLIC_URL +"/images/logo.png"/>
        </MetaTags>
</code>

【问题讨论】:

所以你想在服务器端使用localStorage,对吧? 请检查我的 package.json 文件,让我知道您还需要查看什么 是的,亚历克斯你是对的。 【参考方案1】:

当您在服务器上进行渲染时,您没有浏览器,因此您无法访问浏览器提供的所有 API,包括 localStorage。

在服务器和客户端(浏览器)上运行的 javascript 代码中,通常的做法是使用检查 window 是否已定义的 if 子句进行防范。 “Window”是浏览器为浏览器提供的所有API提供的根对象。

例子:

if (typeof window !== 'undefined') 
    console.log('we are running on the client')
 else 
    console.log('we are running on the server');

在您的情况下,您希望在这样的if 子句中调用localStorage,例如:

if (typeof window !== 'undefined') 
    localStorage.setItem('myCat', 'Tom');

【讨论】:

您问题中的代码在任何地方都没有使用 localStorage。也许它在您要导入的包之一中使用,可能是 react-adsense。但是你没有包括你实际使用它的部分,所以我无法进一步帮助你。 您能否指导我如何在我的应用程序中使用本地存储。或发送任何有用的链接,如果你有的话。 我已经做过或尝试过:无论您使用本地存储,检查它是否真的可用 if 子句,就像我在代码示例中显示的那样 我已经使用了你的代码,但仍然出现同样的错误。 正如@PatrickHund 所说,您可能需要检查依赖项的代码/文档以检查哪个包正在使用localStorage 并将其替换为 s-s-r 友好 包跨度> 【参考方案2】:

您可以将a polyfill 添加到您的应用中。 IE。在您的index.js 某处:

if (!window) 
    require('localstorage-polyfill');

【讨论】:

使用此代码后,我的整个代码都中断了。 --------------------- 出现以下错误。警告:无效的 DOM 属性 class。你的意思是className 不清楚如何链接,但是是的,react 使用className 属性而不是class 我已将此包用于元标记。 npmjs.com/package/react-meta-tags。我想让它对 seo 友好。 这已经是不同的问题,所以我假设您请求帮助的问题已经修复。对于您问的最后一个问题 - 只需将 class 替换为 className,它应该会有所帮助。但是,我注意到将所有内容都转移到服务器端渲染 - 不是一项简单的任务,您可能还会面临其他问题。我建议您为此提出新的具体问题(当然,如果以前没有问过)。我不认为这里有人可以在一个答案中解决您应用中的所有问题。【参考方案3】:

这个oneliner为我做到了:

const checkout = typeof window !== 'undefined' ? localStorage.getItem('checkout') : null

【讨论】:

以上是关于React - 显示“localStorage 未定义”错误的主要内容,如果未能解决你的问题,请参考以下文章

localStorage 未定义(Angular Universal)

使用 WKWebView 时,localStorage 未保存在 iFrame 中

ReferenceError: localStorage 未定义。在 Nextjs 中使用本地存储

使用 Apollo 客户端在 nextJs 中传递授权标头的最佳方法? ReferenceError: localStorage 未定义

如果为“真”则显示组件,否则显示其他组件(在 React 中)

如何使用 wordpress react API 在 react 中显示插件内容