Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useSessionStorage does not store defaultValue in session storage #5230

Closed
LucasLemanowicz opened this issue Nov 9, 2023 · 0 comments · Fixed by #5663
Closed

useSessionStorage does not store defaultValue in session storage #5230

LucasLemanowicz opened this issue Nov 9, 2023 · 0 comments · Fixed by #5663
Labels
Fix Unknown It is not clear whether the can be resolved

Comments

@LucasLemanowicz
Copy link
Contributor

What package has an issue?

@mantine/hooks

Describe the bug

When using useSessionStorage, the defaultValue is never initially saved to sessionStorage, leading to issues when trying to access it from outside the hook (see attached CodeSandbox link). Digging into the code, you can see why it's happening but it's unclear how to properly fix it without affecting the default behavior for others.

The starting point is in this useEffect which would make it seem like it will set a default value if a defaultValue prop is passed in and the value is undefined:

useEffect(() => {
if (defaultValue !== undefined && value === undefined) {
setStorageValue(defaultValue);
}
}, [defaultValue, value, setStorageValue]);

We are passing in a defaultValue that is not undefined so that makes sense so far. But what about value? We can see where value is set:

const [value, setValue] = useState<T>(readStorageValue(getInitialValueInEffect));

Looking into readStorageValue we see this function. Let's deal with it on a case by case basis:

const readStorageValue = useCallback(
(skipStorage?: boolean): T => {
let storageBlockedOrSkipped;
try {
storageBlockedOrSkipped =
typeof window === 'undefined' ||
!(type in window) ||
window[type] === null ||
!!skipStorage;
} catch (_e) {
storageBlockedOrSkipped = true;
}
if (storageBlockedOrSkipped) {
return defaultValue as T;
}
const storageValue = getItem(key);
return storageValue !== null ? deserialize(storageValue) : (defaultValue as T);
},
[key, defaultValue]
);

If skipStorage is set to true:

  • storageBlockedOrSkipped will evaluate to true
  • line 96 will enter the if block and we will return defaultValue as T; which will not be null
  • that means value === undefined on line 146 will be false, and it will not setStorageValue.

If skipStorage is set to false:

  • storageBlockedOrSkipped will in normal situations evaluate to false
  • const storageValue = getItem(key); on line 100 will return null
  • as a result return storageValue !== null ? deserialize(storageValue) : (defaultValue as T); on line 101 will also return the defaultValue which will not be null
  • that means value === undefined on line 146 will be false, and it will not setStorageValue.

What version of @mantine/* packages do you have in package.json? (Note that all @mantine/* packages must have the same version in order to work correctly)

7.2.1

If possible, please include a link to a codesandbox with a minimal reproduction

https://codesandbox.io/s/festive-ptolemy-tw2dmr?file=/src/App.tsx

Do you know how to fix the issue

No

Do you want to send a pull request with a fix?

None

Possible fix

No response

@rtivital rtivital added the Fix Unknown It is not clear whether the can be resolved label Nov 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Unknown It is not clear whether the can be resolved
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants