Created a custom hook for persistent useState

This commit is contained in:
DrMint 2022-02-22 14:31:03 +01:00
parent c4ce6aa11e
commit dc83821ff2
2 changed files with 42 additions and 30 deletions

View File

@ -1,3 +1,4 @@
import useStateWithLocalStorage from "hooks/useStateWithLocalStorage";
import React, { ReactNode, useContext, useEffect, useState } from "react"; import React, { ReactNode, useContext, useEffect, useState } from "react";
export interface AppLayoutState { export interface AppLayoutState {
@ -39,44 +40,32 @@ type Props = {
}; };
export const AppContextProvider = (props: Props) => { export const AppContextProvider = (props: Props) => {
function useLocalStorage( const [subPanelOpen, setSubPanelOpen] = useStateWithLocalStorage<boolean>(
value: boolean, "subPanelOpen",
setter: React.Dispatch<React.SetStateAction<boolean>>,
name: string
): void {
useEffect(() => {
const data = localStorage.getItem(name);
if (data) setter(JSON.parse(data));
}, [setter, name]);
useEffect(() => {
localStorage.setItem(name, JSON.stringify(value));
}, [value, name]);
}
const [subPanelOpen, setSubPanelOpen] = useState<boolean>(
initialState.subPanelOpen initialState.subPanelOpen
); );
const [languagePanelOpen, setLanguagePanelOpen] = useState<boolean>( const [languagePanelOpen, setLanguagePanelOpen] =
initialState.languagePanelOpen useStateWithLocalStorage<boolean>(
); "languagePanelOpen",
initialState.languagePanelOpen
);
const [mainPanelReduced, setMainPanelReduced] = useState<boolean>( const [mainPanelReduced, setMainPanelReduced] =
initialState.mainPanelReduced useStateWithLocalStorage<boolean>(
); "mainPanelReduced",
initialState.mainPanelReduced
);
const [mainPanelOpen, setMainPanelOpen] = useState<boolean>( const [mainPanelOpen, setMainPanelOpen] = useStateWithLocalStorage<boolean>(
"mainPanelOpen",
initialState.mainPanelOpen initialState.mainPanelOpen
); );
const [darkMode, setDarkMode] = useState<boolean>(initialState.darkMode); const [darkMode, setDarkMode] = useStateWithLocalStorage<boolean>(
"darkMode",
useLocalStorage(subPanelOpen, setSubPanelOpen, "subPanelOpen"); initialState.darkMode
useLocalStorage(languagePanelOpen, setLanguagePanelOpen, "languagePanelOpen"); );
useLocalStorage(mainPanelReduced, setMainPanelReduced, "mainPanelReduced");
useLocalStorage(mainPanelOpen, setMainPanelOpen, "mainPanelOpen");
useLocalStorage(darkMode, setDarkMode, "darkMode");
return ( return (
<AppContext.Provider <AppContext.Provider

View File

@ -0,0 +1,23 @@
import { useEffect, useState } from "react";
export default function useStateWithLocalStorage<T>(
key: string,
initialValue: T
): [T, React.Dispatch<React.SetStateAction<T>>] {
const [value, setValue] = useState<T>(initialValue);
useEffect(() => {
try {
const item = localStorage.getItem(key);
if (item) setValue(JSON.parse(item) as T);
} catch (error) {
console.warn(`Error reading localStorage key “${key}”:`, error);
}
}, [setValue, key]);
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [value, key]);
return [value, setValue];
}