[英]localStorage is not defined in Nextjs, Redux and Typescript
I'm facing a problem with my project.我的项目遇到问题。 The problem is ReferenceError: localStorage is not defined
.问题是ReferenceError: localStorage is not defined
。 I'm using Nextjs, and Redux with Typescript.我正在使用 Nextjs,Redux 和 Typescript。
const storedUser: string | null = localStorage.getItem('user'); const user: DisplayUser | null =?.storedUser: JSON;parse(storedUser): null. const storedJwt; string | null = localStorage:getItem('jwt')? const jwt. Jwt =:;storedJwt ? JSON.parse(storedJwt) : null;
I'm using these 2 variables user
and jwt
in here initialState
我在这里使用这两个变量user
和jwt
initialState
const initialState: AuthState = { user: user, jwt: jwt, isLoading: false, isSuccess: false, isError: false, }
And initialState
are used in authSlice function
和initialState
在 authSlice 中使用authSlice function
export const authSlice = createSlice({ name: 'auth', initialState, reducers: { reset: (state) => { state.isLoading = false; state.isSuccess = false; state.isError = false; } }, })
If you are using React.js
or Next.js
and you want to check:如果你使用React.js
或Next.js
并且你想检查:
Browser
(which means you can use the localStorage)如果您在Browser
上(这意味着您可以使用 localStorage)Server
(which means you cannot use localStorage)或者如果你在Server
上(这意味着你不能使用 localStorage) You need to check if the window
variable is not undefined, example:您需要检查window
变量是否未定义,例如:
if (typeof window !== 'undefined') {
console.log('You are on the browser')
// 👉️ can use localStorage here
} else {
console.log('You are on the server')
// 👉️ can't use localStorage
}
similar discussion on github/vercel/next.js/discussions github/vercel/next.js/discussions上的类似讨论
I have a similar issue like this in which I have to get the cart items from the localStorage and pass them to the initial state of redux. I solve it like this below code.我有一个类似的问题,我必须从 localStorage 获取购物车项目并将它们传递给 redux 的初始 state。我像下面的代码一样解决它。
const getFromLocalStorage = (key: string) => {
if (!key || typeof window === 'undefined') {
return ""
}
return localStorage.getItem(key)
}
And then use it in initial state like below code:然后在初始 state 中使用它,如下代码所示:
export const initialState = { cartItems: getFromLocalStorage("cartItems") ? JSON.parse(getFromLocalStorage("cartItems") || '{}') : []};
You cannot run localStorage in Node because it's a browser feature.您不能在 Node 中运行 localStorage,因为它是浏览器功能。 You can run a util and reuse it like this:您可以像这样运行一个实用程序并重用它:
const getFromLocalStorage = (key) => {
if (!key || typeof window === 'undefined') {
return ""
}
return localStorage.getItem('user')
}
You can import this in other files and use it:您可以将其导入其他文件并使用它:
const userId = getFromLocalStorage('userId');
This is the simplest way of using this.这是最简单的使用方法。
Adding onto Omar's answer - if you need to store something from localStorage
in a Redux store, you'd need to grab that information client-side and then pass it into your initial Redux store.添加到 Omar 的答案中 - 如果您需要将localStorage
中的某些内容存储在 Redux 商店中,您需要在客户端获取该信息,然后将其传递到您的初始 Redux 商店中。 Redux itself will not be able to differentiate between client/server side rendering unless you check typeof window !== 'undefined'
. Redux 本身将无法区分客户端/服务器端渲染,除非您检查typeof window !== 'undefined'
。
If you want to use Omar's answer as-is, you would need to make that calculation inside your Redux reducer when the initial state is being calculated.如果您想按原样使用 Omar 的答案,则需要在计算初始 state 时在 Redux 减速器内进行该计算。 I don't recommend bringing that logic inside your reducer (makes it harder to unit test the reducer) - try calculating that logic outside of the initial Redux store, then pass it in (minimal example below)我不建议将该逻辑带入您的减速器(使得对减速器进行单元测试变得更加困难) - 尝试在初始 Redux 存储之外计算该逻辑,然后将其传入(下面的最小示例)
// However you calculate your initial Redux state should replace INITIAL_REDUX_STATE
const [statefulStore, setStatefulStore] = useState(INITIAL_REDUX_STATE);
const reduxStore = createStore(yourReducer, initialStore);
useEffect(() => {
// Once and only once on the initial render, grab the localStorage value
// and update Redux state
setStatefulStore(oldState => {
return Object.assign(oldState, {
ssrValue: localStorage.getItem('user')
});
});
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.