Simplify PortalContext and reduce unnecessary global state
A large tech debt item is the PortalContext. There are two things we should do:
1. Reduce global state
It contains a lot state which could be moved to individual pages to save on performance. Every time any state from PortalContext
gets changed, every single component which consumes the PortalContext
via the useContext
hook re-renders. Having all these state items polluting global state is expensive. It also doesn't encapsulate logic very well. This can make the application logic harder to understand.
As an example, chartCommitters
has no reason to be global state as it is only shown in the graph component. This state should be localized to the graph component.
See the PortalContext
here.
The solution
Localize state for states which don't need to be global.
2. Simplify global state with reducers
The problem
Currently, the PortalContext
provides state values and state setters. The majority of these state values and setters are only called at the same time.
For instance when you update currentUserPortal
you expect orgInfo
, orgRepData
, orgInfo
, isFetchingOrgInfo
(etc...) to also get updated. All this data is related.
So everytime we change the currentUserPortal
we need to remember to call setOrgInfo
, setOrgRepData
, setOrgInfo
, setIsFetchingOrgInfo
, etc. This is error prone because we can miss something. It also introduces a lot of repetition.
The solution
We should stop using useState
and instead look at using useReducer
. This is used for managing complex and interrelated state.
You could then add an action named CHANGE_ORGANIZATION
which would collect all this data and return a single object with all this info as state.
When the user logs in, we can call setCurrentUserPortal
side-by-side with dispatchOrganization('CHANGE_ORGANIZATION', userinfo.organization_id)
(this is just pseudo-code... the userinfo object isn't exactly like this)
This action would be called on login, and when an elevated user decides to preview an organization.
See useReducer in the React docs.