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

Logout handled by reducers #753

Merged
merged 4 commits into from Apr 3, 2017
Merged

Conversation

outoftime
Copy link
Contributor

@outoftime outoftime commented Apr 3, 2017

Removes the logOut() thunk action creator and handles all state transitions directly in reducers.

Flow looks like this:

Workspace component dispatches USER_LOGGED_OUT

projects reducer consumes USER_LOGGED_OUT

  • Retains only current project (see below note on how it knows what the current project is)

ui reducer consumes USER_LOGGED_OUT

  • Closes active submenu if it’s the projects list

user reducer consumes USER_LOGGED_OUT

  • Sets user state to unauthenticated

We do introduce a new pattern to reducers, in order for the project reducer to be able to do the right thing.

When the user logs out, we want to clear all projects out of the list except for the current project. This requires the projects reducer to know what the current project is.

There are several ways to solve this problem without giving the projects
reducer access to the rest of the store:

  1. Have the current project key passed in the action payload by the point of dispatch (e.g. from the Workspace component)
  2. Use a thunk action creator that can introspect the current state and then add the current project key to a dispatched action payload
  3. Duplicate the information in the currentProject subtree, also marking the object in projects as current
  4. Don’t bother trimming the projects store–just enforce a rule that only the current project is visible using a selector

However, each of these approaches has significant disadvantages:

  1. The fact that a reducer needs to know about the current project when consuming USER_LOGGED_OUT is an implementation detail of the store; the component that initially dispatches the action should not need to know this
  2. Thunk action creators are considered harmful and are being removed from our code
  3. It’s a very good idea to keep the Redux store fully normalized.
  4. This approach would lead to an incoherent store state, and we’d have roughly the same problem when the user logs in.

Contra the author of this highly upvoted GitHub issue comment, I don’t think it’s an antipattern for reducers to have access to the entire store. In fact, this is the great strength of Redux—we’re able to model all state transitions based on a universally-agreed-upon answer to the question “what is the current state of the world?” The combineReducers approach to isolating the reducer logic for different parts of the subtree is a very useful tool for organizing code; it’s not a mandate to only organize code that way.

Further, options 1 and 2 above feel a bit ridiculous because, fundamentally, reducers do have access to the entire state. Why would we jump through hoops just to give the reducer information it already has access to?

So: establish a pattern that reducer modules may export a named reduceRoot function, which takes the entire state and performs reductions on it. The top-level root reducer will import this function and apply it to the state after running the isolated reducers using the reduce-reducers module.

When the user logs out, we want to clear all projects out of the list
except for the current project. This requires the projects reducer to
know what the current project is.

There are several ways to solve this problem without giving the projects
reducer access to the rest of the store:

1. Have the current project key passed in the action payload by the
   point of dispatch (e.g. from the Workspace component)
2. Use a thunk action creator that can introspect the current state and
   then add the current project key to a dispatched action payload
3. Duplicate the information in the `currentProject` subtree, also
   marking the object in `projects` as `current`
4. Don’t bother trimming the projects store–just enforce a rule that only
   the current project is visible using a selector

However, each of these approaches has significant disadvantages:

1. The fact that a reducer needs to know about the current project when
   consuming `USER_LOGGED_OUT` is an implementation detail of the store;
   the component that initially dispatches the action should not need to
   know this
2. Thunk action creators are considered harmful and are being removed
   from our code
3. It’s a very good idea to keep the Redux store fully normalized.
4. This approach would lead to an incoherent store state, and we’d have
   roughly the same problem when the user logs in.

Contra the author of [this highly upvoted GitHub issue
comment](reduxjs/redux#601 (comment)),
I don’t think it’s an antipattern for reducers to have access to the
entire store. In fact, this is the great strength of Redux—we’re able to
model all state transitions based on a universally-agreed-upon answer to
the question “what is the current state of the world?” The
`combineReducers` approach to isolating the reducer logic for different
parts of the subtree is a very useful tool for organizing code; it’s not
a mandate to only organize code that way.

Further, options 1 and 2 above feel a bit ridiculous because,
fundamentally, **reducers do have access to the entire state**. Why
would we jump through hoops just to give the reducer information it
already has access to?

So: establish a pattern that reducer modules may export a named
`reduceRoot` function, which takes the entire state and performs
reductions on it. The top-level root reducer will import this function
and apply it to the state *after running the isolated reducers* using
the `reduce-reducers` module.
If a user logs out, and they have the projects list open, it should be
closed (because logged out users can’t switch projects).
And call `userLoggedOut` directly from `Workspace`
@outoftime outoftime merged commit 87e02fa into popcodeorg:master Apr 3, 2017
@outoftime outoftime deleted the log-out-saga branch April 3, 2017 23:44
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

Successfully merging this pull request may close these issues.

None yet

1 participant