Open markedwards opened 1 year ago
The eventually could be the key here. To forcefully clear the storage, call persistor.purge()
as illustrated in the example: https://github.com/apollographql/apollo-cache-persist/blob/405de6fb1e963ab50fa30633fb5e000f91d40540/examples/web/src/App.tsx#L100-L105
client.clearStorage()
clears the apollo client storage (sets it to an empty object), but in order to write this new state to your storage, persist
has to be called on cache-persist. That is controlled by the trigger
option, and if you use background
trigger, the new empty state isn't persisted until you background your app.
Okay, that makes sense, but I think it would be helpful if the FAQ mentioned this detail. Its very easy to read that FAQ, come away with the impression that the persistence is purged on clearStore()
, and unexpectedly have very incorrect behavior (that is a bit difficult to triage as such as well).
A variant that seems to work well for me is:
useEffect(() => {
return client.onClearStore(async () => {
await persistor.purge();
});
}, []);
I think most would expect this to be the default behavior. In fact, is there actually a use-case for not purging when the store is cleared?
is there actually a use-case for not purging when the store is cleared
I'm not aware of such use-case. The only reason I could think of is that purging might be an IO heavy task which could block the main thread, and the app might look frozen once the user taps on sign-out button.
That's why the trigger
option exists, and there's no exception to it when it comes to persistence (such as "persist when app is in background, except for when the store is cleared, then persist immediately").
I see your point though, it's definitely a tricky situation with non-obvious behaviour. Would you mind submitting a PR rewording the FAQ?
What if i have a external logout hook, like this one:
import { client } from '@/apollo';
import useAuthStore from '@/state/auth.state';
import useUserStore from '@/state/user.state';
export const useLogout = () => {
const clearAuthData = useAuthStore((s) => s.clearAuthData);
const clearUserData = useUserStore((s) => s.clearUserData);
const handleLogout = async () => {
clearUserData();
clearAuthData();
client?.restore({});
};
return {
handleLogout,
};
};
How can you export the persistor from the initial config that looks like this:
import React, { useEffect, useState } from 'react';
import { CachePersistor, MMKVWrapper } from 'apollo3-cache-persist';
import { client } from './client.apollo';
import { apolloStorage } from '@/storage';
import { ApolloProvider } from '@apollo/client';
export const CustomApolloProvider: React.FC<React.PropsWithChildren> = ({
children,
}) => {
const [isSetClient, setClient] = useState(false);
useEffect(() => {
async function init() {
const cache = client?.cache;
let newPersistor = new CachePersistor({
cache,
storage: new MMKVWrapper(apolloStorage),
trigger: 'background',
debug: __DEV__,
});
await newPersistor.restore();
setClient(true);
}
init();
}, []);
if (!isSetClient) {
return null;
}
return <ApolloProvider client={client}>{children}</ApolloProvider>;
};
The FAQ states:
This does not appear to work. Data remains in
AsyncStorage
, and is restored bypersistCache()
.