State Management
reducerRegistry
For state management we are using Redux
. To avoid loading all redux modules on the first load when we initialize the store
(for detailed implementation check out store.js
file) we introduced code-splitting as indicated in this article. There are few files that make it possible:
reducerRegistry
- class that enables adding redux reducers to the storeβs reducer after the store has been already created - loading on-demand. This class has aregister
method that we use for adding reducers to the store on-demand.store
- first we register reducers that we need on first load
import reducerRegistry from 'reducerRegistry'; reducerRegistry.register('location', router.reducer);
- we add a listener that listens for new reducers to be registered and replace storeβs reducer whenever that happens (whenever
register
method fromreducerRegistry
class is called).
- first we register reducers that we need on first load
some-example-redux-module
- we split redux code into self-contained modules that comprise of a reducer, actions and initial state. In their index files that combine all of them together (we give them moduleβs name, i.e.dataGlobeSpec.js
) we register module into reduxβs store:reducerRegistry.registerModule('dataGlobeSpec', { actions, reducers, initialState, });
Redux-modules and location
state
As described before we create dedicated store
keys by registering reducers
through the reducerRegistry
class
. We do that to store the data that would back the different components of the app; so content of modals, charts or even the ArcGIS Online portal items specs would be stored that way. A dedicated folder under redux-modules
should be created to take care of this flow. On the other hand, reliyng on redux-first-router location
key inside redux
store, we are using a kind of mixed approach to state management. Beyond _bussiness_ data (stored through redux-modules
) we want to have a shareable current state of the app in every momment; to do that we are updating location
query
params each time a change to the app state is triggered. This changes are handled through selectors
to update components state. More or less this is how it works:
-
Have separated keys inside
location
to reference different types of app state. Weβve created theglobe
key to store app state related to the globe (things likeactiveLayers
,landscapeMode
,zoom
level, globeextent
, camera centrecoordinates
β¦ would go inside that key). Weβve also set aui
key to store other states that do not directly reference globe internals but have influence on layout and widgets state. -
Weβve shamelessly stolen the
utils/state-to-url
folder from Global Forest Watch. It has some utilities toparse
andstringify
query params (doing someatob
encoding, and also have thesetComponentStateToUrl
function that gets used inside componentsactions
to updatelocation
state). -
So inside the pages
selectors
we merge thelocation
state with theinitial state
defined for each page to get the actual state of the app and pass it to page components to define the way they should be displayed (bothglobe
andui
state).
UI and globe params (WIP)
UI params:
- activeCategoryLayers: temporal url parameter to store the active layers of the map layers tab between the data globe and the AOI page. This parameter is reset once we get the needed layers information
- activeLayers: Active layers on the globe