Skip to content

Instantly share code, notes, and snippets.

@jeremylenz
Last active February 23, 2019 23:36
Show Gist options
  • Save jeremylenz/520416ea29453417a12493561606d3ff to your computer and use it in GitHub Desktop.
Save jeremylenz/520416ea29453417a12493561606d3ff to your computer and use it in GitHub Desktop.
Use JavaScript Sets in a Redux reducer to keep track of which features are loading
import { SET_LOADER, CLEAR_LOADER } from '../actions/ui'
// Sets are a great way to track API requests for several different kinds of data.
// See my post about this at http://bit.ly/2Taqu5D
const uiState = {
loading: false,
features: new Set(),
}
export const uiReducer = (state = uiState, action) => {
var newFeatures;
switch (true) {
case action.type.includes(SET_LOADER):
newFeatures = new Set(state.features) // Use new Set() here to avoid mutating state directly.
newFeatures.add(action.meta.feature) // Since this is a Set, newFeatures.add() is idempotent. :)
return Object.assign({}, state, {loading: true, features: newFeatures})
case action.type.includes(CLEAR_LOADER):
newFeatures = new Set(state.features)
if(newFeatures.has(action.meta.feature)) { // This check isn't really needed since delete() would just return false, but it feels cleaner to me
newFeatures.delete(action.meta.feature)
}
const newLoading = (newFeatures.size > 0) // If the set has at least one element, we still need to show the loading indicator.
return Object.assign({}, state, {loading: newLoading, features: newFeatures})
default:
return state;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment