Я создаю приложение в NextJs, используя API Restcountries. Я использую redux для имитации компонента корзины/избранного списка. Но когда я запускаю «сборку», у меня возникает ошибка, говорящая, что «localStorage не определен»
import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "@redux-devtools/extension";
import thunk from "redux-thunk";
import { DefaultState } from "redux/reducers";
import reducer from "../reducers";
function saveToLocalStorage(state: DefaultState) {
try {
const localStorageState = JSON.stringify(state);
localStorage.setItem("statePersist", localStorageState);
} catch (e) {
console.warn(e);
}
}
function loadFromLocalStorage() {
try {
const localStorageState = localStorage.getItem("statePersist");
if (localStorageState === null) return undefined;
return JSON.parse(localStorageState);
} catch (e) {
console.warn(e);
}
return undefined;
}
const storeFactory = () => {
const middlewares = [thunk];
const reduxStore = createStore(
reducer,
loadFromLocalStorage(),
composeWithDevTools(applyMiddleware(...middlewares))
);
reduxStore.subscribe(() => saveToLocalStorage(reduxStore.getState()));
return reduxStore;
};
const midi = storeFactory();
export type Store = ReturnType<typeof storeFactory>;
export type RootState = ReturnType<typeof midi.getState>;
export default storeFactory;
Проблема, которую вы видите, заключается в том, что localStorage (он же window.localStorage) не определен на стороне сервера. Следующий сервер отображает ваши компоненты, поэтому, когда это происходит, и он пытается получить доступ к localStorage, он не может его найти. Вам придется подождать, пока браузер отобразит его, чтобы использовать localStorage.
Для других вариантов использования у вас может быть это окно использования в будущем, вы можете проверить, если (typeof window !== 'undefined')`, что является хорошим способом проверить, находитесь ли вы на клиенте или на сервере.
const ISSERVER = typeof window === "undefined";
if (!ISSERVER) localStorage.setItem(key, value);
Или другим подходом было бы использование динамический импорт с помощью ssr: false Next, хотя это обычно требуется только для более сложных случаев использования (например, если вы импортируете библиотеку диаграмм/графиков или что-то подобное, использующее окно).