I make a system jsonwebtoken in React and use Next.js. I find a problem when I run the code in the browser, that is, “localStorage is not defined”. How can I fix it?
This is my code in file 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) }) }
And it shows error “localStorage is not defined”.
Advertisement
Answer
In the constructor
, as well as componentWillMount
lifecycle hooks, the server is still rendering the component. On the other hand, localStorage exists as part of the browser’s window global, and thus you can only use it when the component is rendered. Therefore you can only access localStorage in the componentDidMount
lifecycle hook. Instead of calling localStorage in the constructor, you can define an empty state, and update the state in componentDidMount
when you can start to call 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 }); }