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

Add feature or document how to reset Apollo store #158

Closed
stubailo opened this issue Apr 29, 2016 · 13 comments
Closed

Add feature or document how to reset Apollo store #158

stubailo opened this issue Apr 29, 2016 · 13 comments
Assignees

Comments

@stubailo
Copy link
Contributor

stubailo commented Apr 29, 2016

For example, when the user logs out we might want to clear our some or all of the data on the client.

@stubailo stubailo added the idea label Apr 29, 2016
@abhiaiyer91
Copy link
Contributor

abhiaiyer91 commented Apr 29, 2016

There's way to achieve this today in Redux. We can compose a HO Root Reducer like

function superMegaRootReducer(state, action) {
   if (action.type === 'USER_LOGOUT') {
      state = undefined
   }
  return rootReducer(state, action);
};

What would be cool is next having a reset middleware, so when i want to do these resets, i can just hit an generic reset action type and handle some function i want to be called in the process.

https://gist.github.com/abhiaiyer91/a8a7ca18a8f9b11faa02c899165d942b

Exposing this could be a way to handle tons of things we know we want to do when a user resets

@stubailo
Copy link
Contributor Author

Yep, just need to add some tests and make sure the client behaves correctly when all of the data disappears!

@stubailo stubailo self-assigned this May 2, 2016
@stubailo stubailo added this to the 5/10 cycle milestone May 2, 2016
@stubailo stubailo assigned abhiaiyer91 and unassigned stubailo May 3, 2016
@abhiaiyer91
Copy link
Contributor

Im thinking we should do the following

  1. ship a Higher Order Reducer so people can reset state of any reducer they want.
  2. Build in reset capability to apolloReducer
  3. write tests
  4. write docs

what do you think?

@stubailo
Copy link
Contributor Author

What's the higher order reducer for?

@abhiaiyer91
Copy link
Contributor

abhiaiyer91 commented May 10, 2016

The higher order reducer is for people who want to reset their normal redux state based on the same state clearing the apolloReducer will have. Thoughts?

So essentially whatever we clear apolloReducer with i can wrap a redux reducer

someReducer: composeResetReducer(someReducer, {})

where composeResetReducer takes a reducer and some initial state

function composeResetReducer(reducer: Function, initialState: any): Function {
  return function composedReducer(state: any, action: Object): any {
    if (action.type === "RESET_STATE") {
      return initialState;
    }
    return reducer(state, action);
  };
}

Could be a nice little utility for peeps

@stubailo
Copy link
Contributor Author

Hmm, I'd rather skip that for now - it doesn't seem relevant to Apollo IMO. I'd rather just document "Apollo uses the RESET_STATE action to reset, feel free to use that in your own reducer" or something like that.

I'd rather not get into the business of writing higher-order reducers for people, that sounds like a Redux thing.

But if you want to write a separate package for that, it would be fine to include that in the docs as a code example!

@abhiaiyer91
Copy link
Contributor

Okay Step 1 function to use. https://github.com/abhiaiyer91/redux-reset

@stubailo stubailo modified the milestone: 5/10 cycle May 11, 2016
@timbotnik
Copy link
Contributor

timbotnik commented Jun 7, 2016

This is a real security issue for users on shared computers, is there currently a mechanism for clearing the state? @helfer @stubailo

@helfer
Copy link
Contributor

helfer commented Jun 7, 2016

I think the current workaround is to explicitly pass the store to apollo on construction, and then remove the reference to that store. I think setting the store content to null wouldn't be enough, because you also want to get rid of history. But then again, I don't know much about Redux, so I'll defer to the experts.

@WilliamHolmes
Copy link

WilliamHolmes commented Jun 11, 2016

FYI:
Your global REDUX state can be reset using...
type: 'RESET'

@timbotnik
Copy link
Contributor

timbotnik commented Jun 14, 2016

So I tried out a store reset using the mechanism described here, but I found the QueryManager threw an exception whenever I dispatched my RESET action.

The internal state for query listeners is actually the issue. If there are outstanding watched queries, it fails inside the broadcastQueries function, since queries is {}, and then you end up here and explode when dereferencing queryStoreValue.

And just to clarify - there seems to be no issue if you make sure that all the watched queries are stopped BEFORE resetting the store (although I am not sure there isn't some other state that might need cleaning up as well).

From my perspective i think a reset API makes sense, since

  1. Otherwise I’d have to learn about how to make a reset reducer myself and this is not exactly straightforward. Actually just to add a reset reducer you have to create your own redux store for Apollo, and you lose some nice things like the crash reporter and the hooks for redux dev tools.
  2. We have in-memory state that also needs to be cleaned up before we can safely clear the store.
  3. We might not always use redux as a store?

@Poincare
Copy link
Contributor

Should now be fixed w/ PR #314.

@rogchap
Copy link

rogchap commented Sep 3, 2016

Not sure if this is a complete example on how to reset the store (especially for a logout scenario). The resetStore func is hidden inside QueryManager; and there is no (clear) way to stop queries that are in flight.

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

No branches or pull requests

7 participants