generated from Dicken/dickendock
41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
import { useCallback, useState } from "react";
|
|
|
|
/**
|
|
* Wie useState, aber der Wert überlebt zusätzlich das Verlassen und erneute
|
|
* Betreten einer Seite (z. B. Scanner -> Geräte -> zurück zu Scanner), ohne
|
|
* dass ein laufender Scan erneut ausgeführt werden muss. Nutzt sessionStorage
|
|
* (pro Browser-Tab, weg nach Schließen des Tabs - bewusst kein dauerhafter
|
|
* Speicher, da es sich um vorübergehende "wartet auf Bestätigung"-Zustände
|
|
* handelt, keine echten Nutzdaten).
|
|
*/
|
|
export function usePersistedState<T>(key: string, initial: T): [T, (value: T | ((prev: T) => T)) => void] {
|
|
const storageKey = `launchpad:${key}`;
|
|
|
|
const [state, setState] = useState<T>(() => {
|
|
try {
|
|
const raw = sessionStorage.getItem(storageKey);
|
|
return raw !== null ? (JSON.parse(raw) as T) : initial;
|
|
} catch {
|
|
return initial;
|
|
}
|
|
});
|
|
|
|
const setPersisted = useCallback(
|
|
(value: T | ((prev: T) => T)) => {
|
|
setState((prev) => {
|
|
const next = typeof value === "function" ? (value as (p: T) => T)(prev) : value;
|
|
try {
|
|
sessionStorage.setItem(storageKey, JSON.stringify(next));
|
|
} catch {
|
|
// z. B. Speicher voll oder Privatmodus - dann bleibt der Zustand
|
|
// wenigstens für den Rest dieser Sitzung im Memory erhalten.
|
|
}
|
|
return next;
|
|
});
|
|
},
|
|
[storageKey]
|
|
);
|
|
|
|
return [state, setPersisted];
|
|
}
|