Skip to content

fix(useLocalStorage): return null after explicit removal instead of initialValue#368

Open
DISCONECTED-png wants to merge 1 commit into
uidotdev:mainfrom
DISCONECTED-png:fix/useLocalStorage-removal-returns-null
Open

fix(useLocalStorage): return null after explicit removal instead of initialValue#368
DISCONECTED-png wants to merge 1 commit into
uidotdev:mainfrom
DISCONECTED-png:fix/useLocalStorage-removal-returns-null

Conversation

@DISCONECTED-png

Copy link
Copy Markdown

Problem

Calling setValue(null) correctly removes the item from localStorage,
but the hook returns initialValue instead of null after removal.

Steps to reproduce:
const [value, setValue] = useLocalStorage('key', 'default');
setValue(null);
// Expected: value === null
// Actual: value === 'default'

Root Causes

Two issues working against each other:

  1. Return value fallbackstore ? JSON.parse(store) : initialValue
    treats a missing key as "never initialized" with no way to distinguish
    it from an intentional removal.

  2. Effect re-seeds storage — the useEffect runs after setState(null)
    (because removing the item triggers a re-render) and immediately writes
    initialValue back into storage, undoing the removal entirely.

Fix

Added a wasRemovedRef to track when the item is explicitly cleared.

  • The useEffect now skips re-seeding when wasRemovedRef.current is true
  • The return value resolves to null instead of initialValue in that case
  • The ref resets when key changes (new key = fresh initialization)

Same fix applies to useSessionStorage which shares the same pattern.

Fixes #344

…nitialValue

When setState(null) is called, item is removed from storage but the hook
was returning initialValue instead of null. Two root causes:

1. Return line fell back to initialValue when store was null, with no way
   to distinguish 'never set' from 'intentionally cleared'
2. useEffect re-seeded initialValue back into storage immediately after removal

Fix: track intentional removals with wasRemovedRef so both the effect and
the return value handle the cleared state correctly.

Fixes: uidotdev#344
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant