I build a React and now I am trying to migrate from React Router dom to Next.js. I made the major changes and refactored the code in; (pages/routes and store.js) but then I got this error "ReferenceError: localStorage is not defined".
19 | const initialState = {
> 20 | access: localStorage.getItem('access'),
| ^
21 | refresh: localStorage.getItem('refresh'),
22 | isAuthenticated: null,
23 | user: null
could you please help me through this?
reducers/auth.js :
import {
LOGIN_SUCCESS,
LOGIN_FAIL,
SIGNUP_SUCCESS,
SIGNUP_FAIL,
ACTIVATION_SUCCESS,
ACTIVATION_FAIL,
USER_LOADED_SUCCESS,
USER_LOADED_FAIL,
AUTHENTICATED_SUCCESS,
AUTHENTICATED_FAIL,
PASSWORD_RESET_SUCCESS,
PASSWORD_RESET_FAIL,
PASSWORD_RESET_CONFIRM_SUCCESS,
PASSWORD_RESET_CONFIRM_FAIL,
LOGOUT
} from '../actions/types';
const initialState = {
access: localStorage.getItem('access'),
refresh: localStorage.getItem('refresh'),
isAuthenticated: null,
user: null
};
export default function (state = initialState, action) {
const { type, payload } = action;
switch(type) {
case AUTHENTICATED_SUCCESS:
return {
...state,
isAuthenticated: true
}
case LOGIN_SUCCESS:
localStorage.setItem('access', payload.access);
localStorage.setItem('refresh', payload.refresh);
return {
...state,
isAuthenticated: true,
access: payload.access,
refresh: payload.refresh
}
case USER_LOADED_SUCCESS:
return {
...state,
user: payload
}
case SIGNUP_SUCCESS:
return {
...state,
isAuthenticated: false
}
case AUTHENTICATED_FAIL:
return {
...state,
isAuthenticated: false
}
case USER_LOADED_FAIL:
return {
...state,
user: null
}
case LOGIN_FAIL:
case SIGNUP_FAIL:
case LOGOUT:
localStorage.removeItem('access');
localStorage.removeItem('refresh');
return {
...state,
access: null,
refresh: null,
isAuthenticated: false,
user: null
}
case PASSWORD_RESET_SUCCESS:
case PASSWORD_RESET_FAIL:
case ACTIVATION_SUCCESS:
case ACTIVATION_FAIL:
case PASSWORD_RESET_CONFIRM_SUCCESS:
case PASSWORD_RESET_CONFIRM_FAIL:
return {
...state
}
default:
return state
}
};
src/store.js
import { useMemo } from 'react';
import { applyMiddleware } from 'redux';
import { legacy_createStore as createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunkMiddleware from 'redux-thunk';
import reducers from './reducers';
let store;
function initStore(initialState) {
return createStore(
reducers,
initialState,
composeWithDevTools(applyMiddleware(thunkMiddleware))
);
};
export const initializeStore = (preloadedState) => {
let _store = store ?? initStore(preloadedState);
// After navigating to a page with an initial Redux state, merge that state
// with the current state in the store, and create a new store
if (preloadedState && store) {
_store = initStore({
...store.getState(),
...preloadedState,
})
// Reset the current store
store = undefined;
}
// For SSG and SSR always create a new store
if (typeof window === 'undefined') return _store;
// Create the store once in the client
if (!store) store = _store;
return _store;
}
export function useStore(initialState) {
const store = useMemo(() => initializeStore(initialState), [initialState]);
return store;
}
Thank you in advance
NextJs using server side render, the window object is not defined there. The thing to do is to check the existence of the window object, or preferably using it only where it is defined, in a useEffect hook for example, the hook executing client side.
You could do something like :
const initialState = {
access: typeof window !== "undefined" ? window.localStorage.getItem('access') : false,
refresh: typeof window !== "undefined" ? window.localStorage.getItem('refresh') : false,
isAuthenticated: null,
user: null
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With