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

persist API: store initial value #366

Closed
kolodziejczak-sz opened this issue Apr 18, 2021 · 13 comments
Closed

persist API: store initial value #366

kolodziejczak-sz opened this issue Apr 18, 2021 · 13 comments
Labels
enhancement New feature or request middleware/persist This issue is about the persist middleware

Comments

@kolodziejczak-sz
Copy link

kolodziejczak-sz commented Apr 18, 2021

Hey guys, first of all, I really like the library! I'd like to extend the PersistOptions API to fit my needs. I'll briefly introduce my use case: I want to set the unique id to the client device, smth like this:

create(persist((() => ({
  id: guuid(),
  ...
}), { name: localStorageKey }));

Every time I refresh the page, the id changes. I'd love to have that state value saved to the localStorage at the time of a new store creation. I'm aware I can declare extra action that sets the id explicitly, but I think an extra property to PersistOptions, smth like { storeInitialValue: boolean } (store only when localStorage.name does not exists) would be a much cleaner solution.
And of course, maybe I'm missing something, but I'd love to hear your feedback on this.

@AnatoleLucet AnatoleLucet added the enhancement New feature or request label Apr 18, 2021
@Mangor1no
Copy link

Mangor1no commented Apr 24, 2021

Your case is, basically, calling the "guuid()" function per re-render time, which leads into the changing of your "id" state. I don't think that a problem with the library, it is more likely that the way to approach your problem haven't correct yet.

@axelboc
Copy link

axelboc commented May 6, 2021

As @Mangor1no mentioned, you can approach the problem another way. For instance, you could set the ID in the store from a useEffect the first time the app renders:

const useStore = create(persist((() => ({
  id: undefined,
  setId: (id) => set({ id })
  ...
})));

function App() {
  const id = useStore(state => state.id);
  const setId = useStore(state => state.setId);

  useEffect(() => {
    setId(guuid());
  }, []); // run effect on mount

  if (id === undefined) {
    return null; // app not ready
  }

  return <>...</> // app ready
}

Alternatively, you could set the new ID to localStorage yourself before calling ReactDOM.render, and then wait for the persist middleware to rehydrate the store (beware, however, that this currently happens asynchronously: #346).

@kolodziejczak-sz
Copy link
Author

thank you for your replies, I'm aware I can get around this problem by using the 'set' fn. I just find it unconvenient that the store value is persisted only after explicit interaction with it.

@dai-shi dai-shi added the middleware/persist This issue is about the persist middleware label May 18, 2021
@byteab
Copy link
Contributor

byteab commented May 20, 2021

@dai-shi we can have { presistedFields: [ "fieldname" ] } inside persistoptions object.
if you will I can work on this.

@dai-shi
Copy link
Member

dai-shi commented May 20, 2021

@dai-shi we can have { presistedFields: [ "fieldname" ] } inside persistoptions object.
if you will I can work on this.

I don't think it's that easy. We also need to take care of AsyncStorage.

(beware, however, that this currently happens asynchronously: #346).

#346 (comment)
We should fix this, and then localStorage users can store initial values before calling create().
You want to work on this?
hint: https://github.com/pmndrs/jotai/blob/8e1366af11251e3873b9fddde5ffd011a469d95c/src/utils/atomWithStorage.ts#L39-L42

@matt-morris
Copy link

I was about to open a new issue, but then I spotted this thread and I think I might be running into the same problem.

This example was adapted from the docs: https://codesandbox.io/s/pedantic-smoke-96udc. The state is random on every load until clicking the button, after which it's persisted correctly.

I took a quick stab based on @axelboc's example: https://codesandbox.io/s/dank-dream-qojuh, but it actually doesn't work at all. The state is random every time, even after clicking the button.

For context, my goal is to store a session token when a user authenticates, and then store a local cache of their data (along with metadata such as the last time it was refreshed). I'm not sure if there's a better way of approaching this.

Any ideas?

@byteab
Copy link
Contributor

byteab commented May 22, 2021

as it seems there is some inconsistency in persisting data.
the data only store in local storage when there is a set operation.

in this repo the data will only store in localstorage when you click on update button.
https://codesandbox.io/s/zustand-persist-debug-0k6ui?file=/src/App.js

@byteab
Copy link
Contributor

byteab commented May 23, 2021

@dai-shi the issue is that persist middleware only persists data when there is a set call.
you can check that on this

#366 (comment)

or this

#366 (comment)

@dai-shi
Copy link
Member

dai-shi commented May 23, 2021

OK, so, it's another async issue on set. In addition to #366 (comment), we'd need to check promise on set.
Basically, we shouldn't use async/await at all (which would also help bundling issue).

Hope you get the point. It's rather a big refactoring.

@byteab
Copy link
Contributor

byteab commented May 23, 2021

Ok, @dai-shi I will look for a solution for async/await

@dai-shi
Copy link
Member

dai-shi commented May 23, 2021

Good. That's the first step. What you were trying to solve is the second step, which could be done after that, if that's really desired.

@byteab
Copy link
Contributor

byteab commented May 23, 2021

Ok, I got it.

  • async await
  • DX

@dai-shi
Copy link
Member

dai-shi commented Dec 5, 2022

Closing this as workarounds are provided and the discussion is a little too broad.

@dai-shi dai-shi closed this as completed Dec 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request middleware/persist This issue is about the persist middleware
Projects
None yet
Development

No branches or pull requests

7 participants