5 ms·
I'd recommend just putting this crap in the URL. That way (a) the server could see it too, and (b) users could share their state by sharing the URL (which makes
by geocar 7y ago
I'd recommend just putting this crap in the URL. That way (a) the server could see it too, and (b) users could share their state by sharing the URL (which makes supporting them easier!). If you've got so much state this doesn't make sense, then ¯\_(ツ)_/¯ I suppose caching it in localStorage is fine, but I haven't yet run into this problem.
Having a setSticky((k,v) => that modifies the url with the history API is pretty easy, and if you get the results using the Context API, you can have your root monitor the URL (again using the history API) and publish the result using a context so you don't have a storm of updates.
- k__ 7y agoUser specific state like "dark mode enabled" would probably be better inside localStorage than inside a shareable URL.
- geocar 7y agoDon't browsers have media queries for things like that? I think some old browsers didn't, so I guess that's why there are all those tacky switches on blogs these days, but I don't usually worry about obsolete things like "made for netscape 4" banners... I also think for an application, I'd much prefer my settings on the server so I can get them again when I'm using another device.
- bobthepanda 7y agoCompatible with everything except IE 11, but in draft: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pref...
- ultrarunner 7y agoWe have an application that's used outdoors day and night in some cases. The good news is it makes a ton of difference in usability; the bad news is I honestly still have to search for instructions on toggling dark mode on Ubuntu. The switch is a lot simpler.
- geocar 7y agoHey go nuts. Whatever works for you. But if you wanted to use other applications that didn't have such a switch, you might consider looking into a hotkey or an extension. I found this[1] after a quick ddg. Maybe it'll help? [1]: https://extensions.gnome.org/extension/2314/dark-mode-switcher/ https://extensions.gnome.org/extension/2314/dark-mode-switch...
- k__ 7y agoSure, it was just an example. :)
- geocar 7y agoI figured as much, but I feel pretty strongly that every piece of state needs to be accessible to a user or to the server, otherwise you lose control of it and that can war on. I know that for performance reasons, or for privacy reasons, or even for time/effort reasons, that's not always possible, but I'm also always genuinely hopeful that there's some new class of data out there that doesn't fall into that (general) rule.
- hinkley 7y agoDisagree. There are whole classes of UI errors that are only reproducible if you use the same look and feel as the customer. Black text on a black background being reported as data loss or missing functionality, for starters, but there are many others.
- Dylan16807 7y agoThat's useful in the specific case of debugging but as a user it would be pretty awful if all my customization disappeared every time I clicked a link from another user. And you want screen resolution and DPI too for a proper "same look and feel" debugging experience. Which you could always hide in the URL if you want, but you shouldn't act on it by default. Do the same thing with UI settings, if you must. Include them but don't act on them.
- hinkley 7y agoThat can also be achieved by storing that information as user preferences on the backend, and it won’t affect your friends but let’s support people figure out what they need to know.
- joshwcomeau 7y agoThat's a neat idea! In the case of something like a blog, though, you anticipate folks sharing the URL. It'd be kinda strange to inadvertently share persisted settings (or worse, stuff that's maybe a little personal)
- geocar 7y agoWhat kind of persisted settings? Surely those things should live in the application, no? Other things like blog gadgets to choose different themes (or whatever) probably should live in the URL to facilitate bug reports! I think Internet users are savvy enough to remove that stuff from a URL when sharing on HN (and if not, the mods seem to). Also, I think it's pretty clear I'm talking about navigation and queries in the above though, just so there's no other confusion: I definitely suggest continuing to use setState or ref for input boxes!
- deleted 7y ago[deleted]
- rbalicki 7y agoThere should be a single useState hook which takes an optional `{persistor, reader}` param. Then the choice of whether to stuff this in local storage, URL, local state, global (transient) state, post it to an endpoint, etc is all configurable depending on the use case.
- geocar 7y agoI've thought about something like that, but then what namespace would the keys belong to? Are they just some kind of hidden "superglobal" and if so, how do you reconcile the intention that state be limited to its component? On the other hand, you could (somehow) build unique symbols for each instance, then have the problem of who's responsibility is it to nominate friendly names for the query string (or yuck, __viewState!)? Or you could make it the persistor's [sic] responsibility; give it this, the key and the value, and let it worry about this exact same problem? Even if you choose one way, there's going to be people who want it a different way, so you've got to be right! I think you really need setState to have some idea who might be interested in this state transition. One idea I had was to have an optional argument to specify the "Persistor" [sic], and then I consult the "Reader" in the constructor to build the initial (local) state, and in for own code, I ended up with something pretty much like that. this.setState({ fields, row: 0 }, UpdateURL) where: setState(x,y) { return y&&y(x)&&super.setState(x); } I haven't had any need for multiple "Persistors" [sic], nor any idea what multiple "Readers" might do, but you should find it easy to add a pub/sub mechanism in there if you needed it.
- nohuhu 7y agoThis is what Statium and Urlito are for: import ViewModel from 'statium'; import stateToUri from 'urlito'; const defaultState = { foo: 'bar', qux: { time: Date.now(), }, }; const [getStateFromUri, setStateToUri] = stateToUri(defaultState, [ 'foo', { key: 'qux.time', uriKey: 'time', fromUri: time => parseInt(time, 10), toUri: time => String(time), }, }); const Component = () => ( <ViewModel initialState={getStateFromUri} observeStateChange={setStateToUri}> {/* ... */} </ViewModel> );