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

purge() doesn't work #1015

Open
rico345100 opened this issue Mar 28, 2019 · 30 comments
Open

purge() doesn't work #1015

rico345100 opened this issue Mar 28, 2019 · 30 comments

Comments

@rico345100
Copy link

Hello. Using persistor.purge doesn't clear any data in my storage.

Here's the code:

const persistor = getPersistor();
await persistor.purge();

getPersistor() function returns persistor, and I called purge function but still nothing changed in my storage.

I also tried this code as well, but doesn't worked either:

const persistor = getPersistor();
await persistor.purge();
await persistor.flush();
await persistor.persist();

It seems like purge doesn't work. Used @5.10.0.

@Trashpants
Copy link

I was confused by this too - not sure if you fixed it by now, but for any people who stumble across this in the future: in order for this to work you have to make sure there is a PURGE action for each reducer that returns your 'clean' state. Then your commands of purge(), flush() will clear and force save the changes.

For reference I am coding with react-native (so I assume this is the same for react)

what's confusing is that if you immediately call purge() after setting up the persistor in store.js it will clear it on boot as expected

@chiaberry
Copy link

@Trashpants, can you elaborate on what a PURGE action is for each reducer? Is the data being erased from the disk, but not in redux? I cannot tell if I'm running into the same issues you are describing. thanks in advance

@chiaberry
Copy link

When I run

persistor.purge()
     .then(response => console.log(response))

response comes back as null, is that expected?

@Trashpants
Copy link

@chiaberry I have multiple reducers implemented with a PURGE case as

import { PURGE } from "redux-persist";

const INITIAL_STATE = {
  token: "",
  loading: false,
  user: {}
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case PURGE:
      return INITIAL_STATE;
    }
 };

that way when I call persistor.purge() its actually setting my state back to INITIAL_STATE

@chiaberry
Copy link

@Trashpants awesome! thank you

@jfbloom22
Copy link

I was having a similar issue, but after I implemented perge() I was still having issues. It turned out to be a race condition where some other action would write to state and trigger persisting data that I expected to be cleared. If a user logged out while an API call was loading, it would cause fun issues. I ended up with:

persistor.purge()
.then(() => {
return persistor.flush()
})
.then(() => {
persistor.pause()
})

@marko-ignjatovic
Copy link

When I run

persistor.purge()
     .then(response => console.log(response))

response comes back as null, is that expected?

And I am getting undefined

@jfbloom22
Copy link

@lolz42 that is expected. The function does not return anything besides a promise.

purge: () => {

@xyz1hang
Copy link

persistor.pause()
persistor.flush().then(() => { return persistor.purge() })

and then depends on your app logic resume it by
persistor.persist()

e.g in login page ?

@EternalChildren
Copy link

i have the same problem. when i upgrade the app
the redux state is older. i think the persistStore make it.
but nothing happened after persistor.purge()

persistor.pause()
persistor.flush().then(() => { return persistor.purge() })

not work for me.
who have the better solutions?

@tparesi
Copy link

tparesi commented Nov 14, 2019

I ran into a similar situation and need to enable remote debugging to have resistor.purge() work as expected on React Native using expo.

@titulus
Copy link

titulus commented Dec 18, 2019

await persistor.purge();
await persistor.purge();

works for me!

@karland
Copy link

karland commented Apr 13, 2020

Works for me:

    const purge = () => {
      persistor.purge()
      console.log("Factory reset performed.")
    }

    <button onClick={() => purge()} >Purge</button>

Does NOT work for me:

    const purge = () => {
      persistor.purge()
      console.log("Factory reset performed.")
    }

    purge()

Also does NOT work for me:

    const purge = async () => {
      await persistor.purge()
      console.log("Factory reset performed.")
    }

    purge()

Solution from @titulus also works for me

    const purge = async () => {
      await persistor.purge()
      await persistor.purge()
      console.log("Factory reset performed.")
    }

    purge()

Alternative solution also works for me:

    const purge = () => {
      persistor.purge()
      console.log("Factory reset performed.")
    }

    setTimeout(() => purge(), 200)

I played around with the delay and it seems to need at least 100ms.

@gleidsonh
Copy link

I just did

setTimeout(() => persistor.purge(), 200)

and works great.

@lsmolic
Copy link

lsmolic commented May 12, 2020

in all seriousness, I think I found the fix. You all want me to submit a PR?

// FiXeD iT
await persistor.purge();
await persistor.purge();
await persistor.purge();
await persistor.purge();
await persistor.purge();
await persistor.purge();
await persistor.purge();

@manikbajaj
Copy link

Strangely it's working with a setTimeout() as posted by @gleidsonh. This needs to be fixed. I was using this in generator with yield in redux-saga and yet somehow promise doesn't return true.

setTimeout(() => persistor.purge(), 200)

I just did

setTimeout(() => persistor.purge(), 200)

and works great.

@gkatsanos
Copy link

gkatsanos commented Jul 7, 2020

I don't understand most of the comments. persistore.purge() as it's clearing localStorage has to be a promise / async. You can await it inside an async function and I'd use a try/catch as well:

export let logout = () => async (dispatch) => {

  try {
    await persistor.purge();
    dispatch(logoutSucceed());
  } catch (err) {
    dispatch(logoutFailed(err));
  }
};

I assume just doing persister.purge() without awaiting or without .then(() => /*do something*/) isn't gonna work.
I guess the documentation could have some more examples.

@bcjohnblue
Copy link

bcjohnblue commented Aug 14, 2020

I am implement redux-persist with redux-saga. I found it clear the localStorage and redux state all together well.

redux-persist version: 6.0.0

import { persistor } from 'src/store' // Self create persistor

export function* logoutSaga() {
  // logoutRequestSuccess() is responsible for clearing the redux state
  yield all([call(persistor.purge), put(logoutRequestSuccess())])
}

@chungmarcoo
Copy link

chungmarcoo commented May 21, 2021

I was faced this kind of problem yesterday, and keep finding the solution across Google / Stack Overflow. And below is my solution that works fine now for people who is stilling struggling right now. My problem that I need to get through yesterday is my redux-persist is not working after my rootReducer reset by return rootReducer(undefined, action);. And here is my solution in my LogoutScreen (i.e. in stack navigation), and my store.js no need to change the original code (i.e. return rootReducer(undefined, action);)

const logoutEffect = () => {
    const {error, success} = authState.remotes.logout;
    if (error || success) {
      dispatch(logoutReset());

      persistor.pause();
      persistor.flush().then(() => {
        return persistor.purge();
      });

      // navigation.navigate('Welcome');
      navigation.dispatch(
        CommonActions.reset({
          index: 1,
          routes: [{name: 'Welcome'}],
        }),
      );

      persistor.persist();
    }
  };

@lsmolic
Copy link

lsmolic commented May 21, 2021 via email

kasperg added a commit to reload/ding2 that referenced this issue May 26, 2021
kasperg added a commit to reload/ding2 that referenced this issue May 26, 2021
@grumpyTofu
Copy link

credit to @Trashpants for the hint, but for those of my fellow Redux Toolkit fans, you need to add an 'extraReducer' on your slice.

import { PURGE } from "redux-persist";

...
extraReducers: (builder) => {
    builder.addCase(PURGE, (state) => {
        customEntityAdapter.removeAll(state);
    });
}

@KonstantinZhukovskij
Copy link

KonstantinZhukovskij commented Jul 30, 2021

This example is for those who use react-native. But I'm pretty sure it will work the same for react.

You must reload your application, this is the whole solution.
You take the NativeModules from react-native

persistor.purge().then(() => NativeModules.DevSettings.reload());

This works great.

@suleymanozev
Copy link

suleymanozev commented Apr 14, 2022

This method is applicable for those who use Redux Toolkit.
The extraReducers method in each slice should contain:

 builder.addCase(PURGE, () => initialState);

Example

import { PURGE } from "redux-persist";
import { AuthUser } from "../types/user";
import { createSlice } from "@reduxjs/toolkit";

export interface AuthState {
  user: AuthUser | null;
  token: string | null;
}

const initialState: AuthState = {
  user: null,
  token: null,
};

const slice = createSlice({
  name: "auth",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(PURGE, () => initialState); // THIS LINE
  },
});

Purge Usage:

persistor.purge().then(() => /** whatever you want to do **/);

@jellyfish-tom
Copy link

@suleymanozev thank you thousand times and more kind sir. Saved me :)

@jdavyds
Copy link

jdavyds commented Sep 14, 2022

credit to @Trashpants for the hint, but for those of my fellow Redux Toolkit fans, you need to add an 'extraReducer' on your slice.

import { PURGE } from "redux-persist";

...
extraReducers: (builder) => {
    builder.addCase(PURGE, (state) => {
        customEntityAdapter.removeAll(state);
    });
}

Whe is the customEntityAdapter importing from?

@nagamejun
Copy link

Whe is the customEntityAdapter importing from?

https://stackoverflow.com/questions/68929107/how-to-purge-any-persisted-state-using-react-tool-kit-with-redux-persist

customEntityAdapter, according to its name, it should be created by createEntityAdapter.

@shubhamGophygital
Copy link

import { persistor } from "../../../../reduxToolkit/store";

const clearPersistData=()=>{
persistor.pause();
persistor.flush().then(() => {
return persistor.purge();
});
}

this worked for me !!!! @chungmarcoo thanks for the help

@probir-sarkar
Copy link

// To clear persisted state data and immediately flush the storage system:
persistor.purge().then(() => persistor.flush());

@lsmolic
Copy link

lsmolic commented Feb 19, 2023 via email

@jmathew
Copy link

jmathew commented Mar 26, 2024

Unless it's been updated, the purge is not a promise, so that will not work. Any positive test cases are just my coincidence.It is a callback and must be handled by passing a function which will execute asynchronously. If you read the source code it will confirm this.

This source indicates its a promise:

purge: () => {

And it seems to have been for the past 6 years:
https://github.com/rt2zz/redux-persist/blame/9526af76e3e64cfe9a55a6c91386349e8dc7a96f/src/persistStore.js#L79

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests