Last active
February 23, 2019 23:36
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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