在 reactjs 和 nextjs 构造函数中获取引用错误:未定义 localstorage

IT技术 javascript node.js reactjs next.js
2021-03-24 05:07:56

我在 reactjs 中创建系统 jsonwebtoken 并使用 nextjs。当我在未定义 localStorage 的浏览器中运行代码时,我发现问题。

这是我在文件 AuthStudentContext.js 中的代码

import React from 'react'
import axios from 'axios'

const axiosReq = axios.create()
const AuthStudentContext = React.createContext()

export class AuthStudentContextProvider extends React.Component {

    constructor() {
        super()
        this.state = {
            students: [],
            student: localStorage.getItem('student') || {},
            token: localStorage.getItem('token') || "",
            isLoggedIn: (localStorage.getItem('student' == null)) ? false : true
        }
    }

    login = (credentials) => {
        return axiosReq.post("http://localhost:4000/api/login", credentials)
            .then(response => {
                const { token } = response.data
                localStorage.setItem("token", token)

                this.setState({
                    token,
                    isLoggedIn: true
                })

                return console.log(response)
            })
    }

并显示错误 localStorage 未定义

4个回答

constructor还有componentWillMount生命周期挂钩,服务器仍呈现组件。另一方面,localStorage作为浏览器 Window 全局的一部分存在,因此您只能在呈现组件时使用它。因此,您只能在componentDidMount生命周期挂钩上访问 localStorage 您可以定义一个空状态,并componentDidMount在可以开始调用 localStorage 时更新状态,而不是在构造函数上调用 localStorage。

constructor() { 
  super()
  this.state = {
    students: [],
    student: undefined
    token: undefined,
    isLoggedIn: undefined
  };
}

componentDidMount() {
  this.login();
  this.setState({
    student: localStorage.getItem('student') || {},
    token: localStorage.getItem('token') || "",
    isLoggedIn: (localStorage.getItem('student' == null)) ? false : true
  });
}

正如大家已经提到的,NextJS 在客户端和服务器上运行。在服务器上,没有localStorage,因此出现undefined错误。

但是,另一种解决方案是在访问localStorage. IE

const ISSERVER = typeof window === "undefined";

if(!ISSERVER) {
 // Access localStorage
 ...localStorage.get...
}

我从未接触过 nextjs,但我猜它相当于 Nuxt.js。因此,当您尝试在客户端访问 localstorage 时,它​​会进行服务器端渲染。

您将需要为此使用componentDidMount()这里有一个例子

componentDidMount(){
   localStorage.setItem('myCat', 'Tom');
   alert("Tom is in the localStorage");
}

编辑:

否则你可以尝试 process.browser

if (process.browser) {
   localStorage.setItem("token", token);
}
我不想要 setItem,但我想要 getItem
2021-05-30 05:07:56

除了@SILENT 所说的,这对我有用

 React.useEffect(() => {
    if (localStorage) {
      const getLocalState = localStorage.getItem("headless");
      console.log("LocalState: ", getLocalState)
    }
  }, []);