Closed smamun19 closed 1 year ago
You need to do typeof window !== 'undefined'
for storage
. See below:
export class UserStore {
user: IUser | null = null;
constructor() {
makeAutoObservable(this, {}, { autoBind: true });
makePersistable(this, {
name: "UserStore",
properties: ["user"],
storage: typeof window !== 'undefined' ? window.localStorage : undefined,
});
}
}
Thanks for your answer. I am facing another issue that is when I go another page the data do not persist. It persist only at home page
I would have to see your store setup. Can you provide snippets of you code?
rootStoreProvider.tsx
import { RootStore } from "./root";
const RootStoreContext = createContext<RootStore>(new RootStore());
export const useStore = () => {
const context = useContext(RootStoreContext);
if (context === undefined) {
throw new Error("useStore must be used within StoreProvider");
}
return context;
};
let rootStore: RootStore | undefined;
const initializeStore = (initialData?: RootStore) => {
const _rootStore = rootStore ?? new RootStore();
if (initialData) {
_rootStore.hydrate(initialData);
}
if (typeof window === "undefined") return _rootStore;
if (!rootStore) rootStore = _rootStore;
return _rootStore;
};
interface Props {
children: React.ReactNode;
intialState?: RootStore;
}
export const RootStoreProvider: FC<Props> = ({ children, intialState }) => {
const store = initializeStore(intialState);
return (
<RootStoreContext.Provider value={store}>
{children}
</RootStoreContext.Provider>
);
};
rootStore.ts
import { hydrateStore, makePersistable } from "mobx-persist-store";
import localforage from "localforage";
export class RootStore {
user: UserStore;
constructor() {
this.user = new UserStore(this);
makePersistable(
this.user,
{
name: "RootStore",
properties: ["details", "cart"],
storage: typeof window !== "undefined" ? localforage : undefined,
},
{ delay: 200, fireImmediately: false }
);
}
async hydrate(data: RootStore): Promise<void> {
await hydrateStore(data);
}
}
It might be an issue with how you use hydrateStore
. Try:
async hydrate(data: RootStore): Promise<void> {
- await hydrateStore(data);
+ await hydrateStore(this.user);
}
Also every time RootStore
is created you should use https://github.com/quarrant/mobx-persist-store#stoppersisting to make sure you clean up.
Take a look at how I did MobX in Next.js https://github.com/codeBelt/react-mobx-persist-store-example .
I would put makePersistable
inside UserStore
and not within RootStore
.
Sorry for the late reply. I'll check your repo as soon as I return home. Would you please elaborate the last part? Why should I put makePersistable
inside UserStore
?
I think the individual stores should be responsible for persisting their own data. What if you added another store to RootStore? How would you persist that data in the RootStore?
export class RootStore {
user: UserStore;
anotherUser: AnotherStore;
constructor() {
this.user = new UserStore(this);
this.anotherStore = new AnotherStore(this);
}
}
export class AnotherStore {
someData: number = 0;
otherData: string = '';
constructor() {
makeAutoObservable(this, {}, { autoBind: true });
makePersistable(this, {
name: "AnotherStore",
properties: ["someData", "otherData"],
storage: typeof window !== 'undefined' ? window.localStorage : undefined,
});
}
}
Also if you have multiple stores with the same storage
you look at https://github.com/quarrant/mobx-persist-store#global-configuration. It is one less thing to repeat in your code.
Thank you very much for your valuable time :) I have successfully configured mobx . I am closing this issue now.
Does this package work with next.js? If it does , how do I configure it with next.js?