quarrant/mobx-persist-store

How to deal with Fast Refresh on React Native?

Closed this issue ยท 11 comments

ftzi commented

I have makePersistable in my init(), so I can await it, to have the values loaded before moving on.

But, on fast refresh, on React Native, it will trigger a warn that makePersistable was called with the same name.

I have tried using if (!isPersisting(this)) and then makePersistable, but it won't always work for some reason.

Does anyone have experience and a workaround for this issue?

ftzi commented

It would be good if there was a function that had the same lines found on

const hasPersistedStoreAlready = Array.from(PersistStoreMap.values())
.map((item) => item.storageName)
.includes(mobxPersistStore.storageName);

ftzi commented

I've done this. It's ugly, but works. This lib could really have this integrated!

image

Anyway, thanks for the lib! It's really useful and pretty.

I've done this. It's ugly, but works. This lib could really have this integrated!

image

Anyway, thanks for the lib! It's really useful and pretty.

doing this will make it so isHydrated returns false

I wonder if these feature will solve your issue? #82

I wonder if these feature will solve your issue? #82

I don't think it's related.
currently in react native "0.67.4": after editing code fast refresh will reload the store but not remove the store from PersistStoreMap

  constructor() {
    makeAutoObservable(this, {}, { autoBind: true });
    const persist = () => {
      makePersistable(this, {
        name: 'userStore',
        properties: [
          'user',
          'accessTokenBlock'
        ],
        storage: AsyncStorage,
      });
    };
    const persistedStore = Array.from(PersistStoreMap.values()).find((el) =>
      el.storageName.includes('userStore')
    );
    if (persistedStore) {
      persistedStore.stopPersisting();
    }
     persist();
  }

with this I no longer receive makePersistable was called with the same name. and store becomes hydrated after fast refresh

do you think this is an ok solution?

EDIT:
#82 could work if i could hydrate a store without going through makePersistable process as long as it won't give this warning: makePersistable was called with the same name.,
but since reload creates a new class', then this is different than the previous one, so I think it wouldn't work

When you say "fast refresh" is that the same a React hot reloading? I have noticed during development mode I will get the warning you are get but when I have a product build I don't see the warning and everything works as expected. It might be a development issue and I wouldn't create a work around just to hide the warning. It's a warning and not a error so you can ignore it in dev mode.

When you say "fast refresh" is that the same a React hot reloading? I have noticed during development mode I will get the warning you are get but when I have a product build I don't see the warning and everything works as expected. It might be a development issue and I wouldn't create a work around just to hide the warning. It's a warning and not a error so you can ignore it in dev mode.

yeah it's basically the same as React hot reload.
I would like to prevent the warning from showing because my 'PersistStoreMap' size quickly grows since I have several stores in my project, and every time I save it adds 4 more into PersistStoreMap

I wonder if we change the PersistStoreMap from a Map to a WeakMap if that will fix the issue when developing. I can look into this.

@quarrant can you re-open this issue?

@codeBelt @quarrant
Has there been progress on this?

For anyone still searching solution

import { PersistStoreMap, makePersistable } from 'mobx-persist-store'

export const makeReloadPersistable: typeof makePersistable = (
	object,
	options
) => {
	for (const [key, store] of PersistStoreMap.entries()) {
		if (store.storageName === options.name) {
			store.stopPersisting()
			PersistStoreMap.delete(key)
		}
	}
	return makePersistable(object, options)
}

Then just replace all makePersistable calls with makeReloadPersistable