uidotdev / usehooks

A collection of modern, server-safe React hooks – from the ui.dev team
https://usehooks.com
MIT License
9.29k stars 496 forks source link

useLocalStorage converts Infinity to null #247

Open SteveVanOpstal opened 11 months ago

SteveVanOpstal commented 11 months ago
const [number, setNumber] = useLocalStorage("number", Infinity);
console.log(number); // null

Seems to be related to JSON.stringify.

You can workaround this issue by not using Infinity but it would be nice to use this interface as you expect it.

ngoue commented 11 months ago

I disagree that this belongs here as an issue. This is exactly how the standard was defined to behave:

https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript

tylermcginnis commented 11 months ago

Related: https://github.com/uidotdev/usehooks/issues/253

SteveVanOpstal commented 11 months ago

I disagree that this belongs here as an issue. This is exactly how the standard was defined to behave:

https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript

It's not necessarily a software issue but coming across this I had the expectation, given that it's a blackbox function, that there were no restrictions. Only after looking at the source code I realised that it uses JSON.stringify to convert it to a string for localStorage, hence it is not able to handle Infinity and NaN. It might just come down to mentioning this in the docs.

philg-ygt commented 10 months ago

I agree with @SteveVanOpstal here: the use of JSON.stringify adds further constraints to the already existing constraints in place when using localStorage.setItem.

If, for example, you decide to send in an object and thus get [object Object] back, that's on you for not supplying a primitive, same as if you were using .setItem directly. It isn't the place of a hook to serialise input, particularly when there is no corresponding deserialising of the output; there is no JSON.parse wrapping localStorage.getItem in getLocalStorageItem...