pmndrs / valtio

🧙 Valtio makes proxy-state simple for React and Vanilla
https://valtio.dev
MIT License
9.1k stars 253 forks source link

Save state to localStorage using Valtio #182

Closed deadcoder0904 closed 3 years ago

deadcoder0904 commented 3 years ago

I stumbled upon Valtio thanks to Leigh Halliday's video titled "The easiest React global state management library - no context/providers!"

The title made me click!

I've been using MobX for a while now & I love that there is https://github.com/quarrant/mobx-persist-store which saves state to localStorage.

Basically, I use MobX exactly as Valtio is made by using custom useStore hook like https://codesandbox.io/s/mobx-persist-store-4l1dm?file=/src/context.ts so I would like to use valtio as it requires just 1 package & less boilerplate on my end.

How do I save state to localStorage? Just use subscribe & save each property? Would appreciate an example in React. Another thing I would love to see is a complex multi-store example. And comparison with Zustand, Jotai & other state-management libs as Valtio looks simplest :)

This is the easiest state-management solution so thank you.

dai-shi commented 3 years ago

persist

If your state is JSON serializable, it should be pretty straightforward.

const state = proxy(JSON.parse(localStorage.getItem('foo')) || {
  count: 0,
  text: 'hello',
})

subscribe(state, () => {
  localStorage.setItem('foo', JSON.stringify(state))
})

If you have non serializable values, attach them after deserialization and exclude them for serialization.

multi store

states are objects and can be nested. Would you describe your requirement without mobx knowledge?

comparison with zustand

https://twitter.com/dai_shi/status/1371839052232716296 https://twitter.com/dai_shi/status/1394576149133467651 https://twitter.com/dai_shi/status/1391693358305734666

comparison with jotai

https://github.com/pmndrs/valtio/issues/141

other comparisons

https://twitter.com/dai_shi/status/1372705718764068865 https://twitter.com/dai_shi/status/1402258862753812481 https://twitter.com/dai_shi/status/1342464894155640833 https://twitter.com/dai_shi/status/1381252474682535938 https://twitter.com/dai_shi/status/1348257768130560008

deadcoder0904 commented 3 years ago

your setItem API confused me without foo. thought where do you set foo 🤔

states are objects and can be nested. Would you describe your requirement without MobX knowledge?

just a simple app with multiple stores. I guess I can just create a simple export like const stores = { userStore, authStore }

honestly, a wiki page of the illustrations is good to show differences as many people will have the same question & opening 10 twitter links makes it cumbersome.

i loved the comparisons. valtio is simplest. tbh its so simple that i have doubts it even works 🤣

i'll report back when i use valtio. i feel like localStorage could be much simpler like using its own state in a class that gets the data, sets it, deletes it & resets the whole store rather than doing it individually one-by-one.

dai-shi commented 3 years ago

your setItem API confused me without foo. thought where do you set foo 🤔

Oops, fixed now.

just a simple app with multiple stores. I guess I can just create a simple export like const stores = { userStore, authStore }

You could have it in a single state.

const state = proxy({
  user: { ... },
  auth: { ... },
})

Actually, you are making a good point. For me, it's just JS object, and pretty straightforward, but people with different background might get confused.

It's sort of doc/education issue. There's room for improvement. So, your feedbacks are appreciated.

honestly, a wiki page of the illustrations is good to show differences as many people will have the same question & opening 10 twitter links makes it cumbersome.

I made wiki open for any contributors for now. Please feel free to make a page. I would just appreciate it. If you need some reviews, please let me know. (in github issues/discussions or discord.)

i loved the comparisons. valtio is simplest. tbh its so simple that i have doubts it even works 🤣

hehe.

i'll report back when i use valtio. i feel like localStorage could be much simpler like using its own state in a class that gets the data, sets it, deletes it & resets the whole store rather than doing it individually one-by-one.

No need to do one-by-one. Please show me what you would like to do. Here's the deal: you can ask me small questions, and I can answer, then you can create a wiki page.

deadcoder0904 commented 3 years ago

Cool, will do. Adding valtio to my new project which is not that complex but should get things rolling. Will open Wiki page too in a few days :)

PS: What's your technique for naming things? They are all so good.

zcaudate commented 3 years ago

you can create observable objects really easily by attaching functions that change the proxy itself:

obj = proxy({data: 1})
obj.inc = () => obj.data += 1
obj.inc() ;; will notify all subscribers
dai-shi commented 3 years ago

https://github.com/pmndrs/valtio/wiki/How-to-persist-states just made a wiki page. feel free to improve it.

HananoshikaYomaru commented 3 years ago

how about persisting the data NOT using localStorage? Isn't localStorage a client side thing and doesn't available in Node?

dai-shi commented 3 years ago

Do you mean file system in Node?

deadcoder0904 commented 3 years ago

how about persisting the data NOT using localStorage? Isn't localStorage a client side thing and doesn't available in Node?

@HananoshikaYomaru Isn't Valtio a client-side state-management library? On server, you save the data in a database like SQL, MongoDB, PostgreSQL, etc...

HananoshikaYomaru commented 3 years ago

@deadcoder0904 sorry for using the inappropriate term. Yes, Valtio is a client side state management library, but what I mean is that I cannot find any localStorage in my react project. I search it online and I found that it is a thing of browser but not in node.

@dai-shi I think the localStorage of Node internally use file system although actually I don't know under the hood. What I see is that Node doesn't expose any localStorage API for me to persist my state.

I wonder if anything like atomWithStorage in Jotai and persist in zustand will be developed in Valtio

dai-shi commented 3 years ago

So, do you want to avoid the react app error in server?

const state = proxy(JSON.parse(typeof localStorage !== 'undefined' && localStorage.getItem('foo')) || {
  count: 0,
  text: 'hello',
})

subscribe(state, () => {
  if (typeof localStorage !== 'undefined') {
    localStorage.setItem('foo', JSON.stringify(state))
  }
})