⚠️ Malware / Trojaner / VirenSafe Link spinnt: Defender stuft harmlose Google-Links als Malware ein(02.09.2026 um 18:26 Uhr)
🔧 AI Nachrichten ChatGPT fällt aus - OpenAI bestätigt Störung vor "Astra"-Start(03.09.2026 um 18:17 Uhr)
🔧 AI Nachrichten Tour mit KI geplant: Amateur-Bergsteiger müssen gerettet werden(04.09.2026 um 15:41 Uhr)
📰 IT Security NachrichtenVolkswagen-Umbau: VW-Spitze beschließt einstimmig Zukunftsplan(05.09.2026 um 09:16 Uhr)
📰 IT Security NachrichtenEU-Zollreform 2026: Weitere Gebühr für günstige Pakete beschlossen(05.09.2026 um 09:48 Uhr)
🕵️ SicherheitslückenWhatsApp-Schwachstelle: Zugriff auf Fotos bei gesperrtem Android-Handy(03.09.2026 um 09:18 Uhr)
⚠️ Malware / Trojaner / VirenSafe Link spinnt: Defender stuft harmlose Google-Links als Malware ein(02.09.2026 um 18:26 Uhr)
🔧 AI Nachrichten ChatGPT fällt aus - OpenAI bestätigt Störung vor "Astra"-Start(03.09.2026 um 18:17 Uhr)
🔧 AI Nachrichten Tour mit KI geplant: Amateur-Bergsteiger müssen gerettet werden(04.09.2026 um 15:41 Uhr)
📰 IT Security NachrichtenVolkswagen-Umbau: VW-Spitze beschließt einstimmig Zukunftsplan(05.09.2026 um 09:16 Uhr)
📰 IT Security NachrichtenEU-Zollreform 2026: Weitere Gebühr für günstige Pakete beschlossen(05.09.2026 um 09:48 Uhr)
🕵️ SicherheitslückenWhatsApp-Schwachstelle: Zugriff auf Fotos bei gesperrtem Android-Handy(03.09.2026 um 09:18 Uhr)

26 🕛 kürzlich 9 Min Lesezeit
0

A Simple React Hook for localStorage State, Expiry, and Sync

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Hi everyone! I'm Gaurav, and I am incredibly excited to share my very first article with the DEV Community! As a developer, I love building open-source tools that solve everyday workflow headaches and make life a bit easier for the community. I wrote this article to share what I learned while building my latest package, and I hope it helps you level up your React storage management.



When we build React apps, we often need to save small values in the browser.



For example:




  • selected theme

  • user settings

  • form draft

  • search filters

  • temporary session value

  • cached API response



The browser already gives us localStorage, but using it directly in React can become repetitive.



We usually need to:




  • read the value from localStorage

  • parse the saved JSON

  • handle missing or broken data

  • update React state

  • write the new value back to localStorage

  • remove the value when needed

  • sync the value between tabs

  • expire old values after some time



This is why I built @gks101/localyx.



It is a small React hook that helps you use localStorage like normal React state.






Main Features




  • simple useState-like API

  • saves state in localStorage

  • Same Tab and Cross Tab Sync

  • TTL expiry support

  • absolute and sliding expiry strategies

  • namespace support

  • custom serializer support

  • custom encrypt and decrypt support

  • helper function to check remaining TTL



Working demo:




CODE
https://localyx.vercel.app/





GitHub repo:



CODE
https://github.com/gaurav101/localyx





NPM package:



CODE
npm install @gks101/localyx







What Problem Does It Solve?



React state is simple:



CODE
const [value, setValue] = useState("hello");





But normal React state is lost when the page is refreshed.



localStorage can keep data after refresh, but it does not work like React state by default.



So I wanted a hook that feels like useState, but also saves the value in localStorage.



That is the main idea of useLocalStorageState.





Basic Usage



First install the package:



CODE
npm install @gks101/localyx





Then import the hook:



CODE
import { useLocalStorageState } from "@gks101/localyx";





Now use it inside a component:



CODE
import { useLocalStorageState } from "@gks101/localyx";

function ThemeToggle() {
const [theme, setTheme, clearTheme] = useLocalStorageState("theme", "light");

return (
<div>
<p>Current theme: {theme}</p>

<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Toggle Theme
</button>

<button onClick={clearTheme}>
Reset Theme
</button>
</div>
);
}





This looks very close to useState.



The hook returns three values:



CODE
const [state, setState, removeValue] = useLocalStorageState(key, initialValue);







Step 1: The Key



The first value is the localStorage key.



CODE
useLocalStorageState("theme", "light");





Here, "theme" is the key.



The hook will save the value in localStorage using this key.





Step 2: The Initial Value



The second value is the default value.



CODE
useLocalStorageState("theme", "light");





Here, "light" is the initial value.



The hook will use this value when:




  • nothing is saved in localStorage

  • the saved data is invalid

  • the saved data has expired

  • you remove the value





Step 3: Reading the State



The first returned value is the current state.



CODE
const [theme] = useLocalStorageState("theme", "light");





You can show it in your UI:



CODE
<p>Current theme: {theme}</p>





When the page refreshes, the hook reads the saved value from localStorage.





Step 4: Updating the State



The second returned value is the setter function.



CODE
const [theme, setTheme] = useLocalStorageState("theme", "light");





You can use it like setState:



CODE
setTheme("dark");





You can also use the previous value:



CODE
setTheme((oldTheme) => oldTheme === "light" ? "dark" : "light");





When you call setTheme, the hook updates React state and also saves the new value in localStorage.





Step 5: Removing the Value



The third returned value removes the saved data.



CODE
const [theme, setTheme, clearTheme] = useLocalStorageState("theme", "light");





Use it like this:



CODE
clearTheme();





This removes the value from localStorage and sets the state back to the initial value.





TTL: Expire Data After Some Time



Sometimes we do not want to keep data forever.



For example, a session value or cache value should expire after some time.



TTL means "Time To Live".



You can pass ttl in milliseconds.



CODE
import { useLocalStorageState } from "@gks101/localyx";

function SessionExample() {
const [session, setSession, clearSession] = useLocalStorageState<string | null>(
"session",
null,
{
ttl: 30 * 60 * 1000,
}
);

return (
<div>
<p>{session ?? "No active session"}</p>

<button onClick={() => setSession("my-session-token")}>
Login
</button>

<button onClick={clearSession}>
Logout
</button>
</div>
);
}





In this example, the session expires after 30 minutes.



After expiry, the hook removes the old value and returns the initial value.





Absolute TTL



By default, TTL uses the absolute strategy.



This means the timer starts when the value is saved.



Example:



CODE
const [token, setToken] = useLocalStorageState("token", null, {
ttl: 10 * 60 * 1000,
ttlStrategy: "absolute",
});





If the value is saved at 10:00, it will expire at 10:10.



Even if the user keeps using the app, the value still expires at that time.



This is useful for things like:




  • login session expiry

  • one-time temporary values

  • short-lived cache





Sliding TTL



The hook also supports sliding TTL.



CODE
const [searchCache, setSearchCache] = useLocalStorageState("search_cache", "", {
ttl: 5 * 60 * 1000,
ttlStrategy: "sliding",
});





Sliding TTL refreshes the timer when the value is read or synced.



This means active data can stay alive while the user is still using it.



This is useful for:




  • active session-like data

  • recently used filters

  • temporary UI cache





Run Code When a Value Expires



You can pass onExpire.



This function runs when the hook finds that the value has expired.



CODE
const [token, setToken] = useLocalStorageState("token", null, {
ttl: 10 * 60 * 1000,
onExpire: ({ key, value }) => {
console.log("Expired key:", key);
console.log("Expired value:", value);
},
});





This is useful when you want to:




  • show a message

  • logout the user

  • clear related data

  • send an analytics event





Namespaces



Sometimes many features use localStorage.



To avoid key conflicts, you can use a namespace.



CODE
const [profile, setProfile] = useLocalStorageState("profile", null, {
namespace: "my-app",
});





This stores the value using this key:



CODE
my-app:profile





Namespaces are useful when:




  • you have many stored values

  • you are building a large app

  • you want to separate app versions

  • you want cleaner localStorage keys





Same Tab and Cross Tab Sync



If you open the same app in two browser tabs, the hook can keep values in sync.



For example:




  1. Open the app in Tab 1.

  2. Open the app in Tab 2.

  3. Change the theme in Tab 1.

  4. Tab 2 gets the new value too.



The hook also handles same-tab sync.



This is useful when two components use the same storage key on the same page.





Get Remaining TTL



The package also exports getRemainingTtl.



This helper tells you how much time is left before a saved value expires.



CODE
import { getRemainingTtl } from "@gks101/localyx";

const remainingMs = getRemainingTtl("session", 30 * 60 * 1000);

console.log(remainingMs);





It returns:




  • a number if time is remaining


  • 0 if the value is already expired but not cleaned yet


  • null if the key does not exist or the value has no TTL data



You can also use it with a namespace:



CODE
const remainingMs = getRemainingTtl("session", 30 * 60 * 1000, {
namespace: "my-app",
});







Custom Serialization



By default, the hook uses JSON.



For most React apps, that is enough.



But you can provide your own serializer if you need custom behavior.



CODE
const [value, setValue] = useLocalStorageState("custom", "hello", {
serializer: {
stringify: (value) => JSON.stringify(value),
parse: (value) => JSON.parse(value),
},
});





This is useful when you want more control over how data is saved and loaded.





Encoding and Encryption



By default, the hook stores data with Base64 encoding.



Base64 is only obfuscation. It is not real security.



If you need real security, pass your own encrypt and decrypt functions.



CODE
const encrypt = (raw: string) => {
return btoa(raw);
};

const decrypt = (raw: string) => {
return atob(raw);
};

const [secret, setSecret] = useLocalStorageState("secret", "hello", {
encrypt,
decrypt,
});





If you want to store plain JSON without Base64 encoding, pass null:



CODE
const [value, setValue] = useLocalStorageState("plain", "hello", {
encrypt: null,
decrypt: null,
});





Important note: do not store highly sensitive data in localStorage unless you fully understand the security risks.





SSR Safe



The hook has guards for browser-only APIs.



This means it can be used in apps that render on the server, like Next.js.



It will not directly access window or localStorage when they are not available.





Where Can You Use This Hook?



You can use this hook in many React projects.



Good use cases:




  • dark mode or theme setting

  • language preference

  • sidebar open or closed state

  • table filters

  • search filters

  • sort order

  • form draft

  • shopping cart for small projects

  • temporary session value

  • API cache with expiry

  • feature flag cache

  • onboarding step progress

  • recently viewed items



Avoid using it for:




  • passwords

  • private tokens without a security plan

  • very large data

  • data that must always be correct on the server





You Can Also Copy the Hook Into Your Project



You do not have to use the npm package if you do not want another dependency.



You can also copy the hook file from the GitHub repo and use it directly in your project.



Repo link:



CODE
https://github.com/gaurav101/localyx





This can be useful when:




  • you want full control over the code

  • you want to change the hook for your app

  • you are learning how the hook works

  • you want to avoid adding a package





Full API



Main hook:



CODE
useLocalStorageState<T>(key, initialValue, options?)





It returns:



CODE
[state, setState, removeValue]





Options:



CODE
{
ttl?: number;
ttlStrategy?: "absolute" | "sliding";
namespace?: string;
onExpire?: (ctx: { key: string; value: T }) => void;
now?: () => number;
encrypt?: ((raw: string) => string) | null;
decrypt?: ((raw: string) => string) | null;
serializer?: {
stringify: (value: T) => string;
parse: (value: string) => T;
};
}





Helper:



CODE
getRemainingTtl(key, ttl, options?)







Final Thoughts



I built @gks101/localyx because I wanted a simple way to use localStorage in React without writing the same logic again and again.



It gives you a useState-like API, but also adds useful features like expiry, sync, namespaces, and custom serialization.



If you are a React beginner, you can start with the basic example first.



Later, when you need expiry or sync, the hook already supports it.



Package:



CODE
npm install @gks101/localyx





GitHub:



CODE
https://github.com/gaurav101/localyx





I would absolutely love to hear your thoughts, feedback, or any questions you have in the comments below—let's connect!








Full-stack developer passionate about building scalable applications and exploring new technologies. - gaurav101



favicon
github.com



Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 39%
🟡 In Evaluierung 28%
🟢 Keine Auswirkung 17%
Spannende Innovation 16%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Safe Link spinnt: Defender stuft harmlose Google-Links als Malware ein
1 Quelle
Überlebenskampf per Prompt: Google-KI schickt MrBeast in die Wildnis
1 Quelle
ChatGPT fällt aus - OpenAI bestätigt Störung vor "Astra"-Start
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten A Simple React Hook for localStorage State, Expiry, and Sync

Thematisch verwandte Begriffe: Simple, React, Hook, localStorage · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...