Managing global state with React’s Hooks & Context API
Alternative to Redux for complex React application

In complex React application with multiple components, there is requirement for global state management. As of now most popular approach for global state is Redux, but with new changes in React there might be space for global state management using just React. However note that this approach is not necessarily performance improvement, but rather an approach to remove external package.
Please follow up on Hooks and Context, to familiarize with later approach.
React state management before Redux
In order to understand, React state management and Redux role in that, lets get started how state management was achieved previously using React.
This is simple global state management approach, and kind of looks messy. Here <App>
component will keep global state as its this.state
. It will be passed to child components as props
. When this.state
change is required, there will be function at root<App>
component level using this.setState
. However when child component needs to change global state, these callback functions (Eg: changeLanguage), will have to passed as props. In above example <LanguagePicker>
will execute callback function and it’ll change state in <App>
root component, and updated state again passed to <Lang>
.
As seen, this will be mess for large number of components when single complex store have to be managed at root level. Moreover props drilling will occur where at each child component, all props passed should be mapped to its child. All callback functions have to be defined at <App>
, and thereby all logic should be handled at root level. Thereby different approach is required for complex application, for simplicity and separation of concern.
Global state management using Redux
Here, its assumed that y’all are familiar with Redux approach and wouldn't go into in depth of configuring and using. Simply Redux will manage global store within the application. Within the React application each component can directly access this global store, and only acquire whats required. Any changes that needs to be applied to store will be done through actions and reducers. This means its one-way data binding in Redux, where React application would not directly manipulate global Redux store, but rather invoke functions with logic to do so.

Here above entire application wouldn't be re-written with Redux, as it out of scope of this article. But here is how react components will interact with redux store using react-redux connect function.
Here <Menu>
component is connected with Redux store using connect function. Here values are manipulated using following functions.
export default connect(
mapStateToProps, → GET FROM GLOBAL STORE
mapDispatchToProps → SET TO GLOBAL STORE
)(Menu)
Here without any intermediary components, Redux store can directly be connected to required component. This will reduce unnecessary re-rendering and can divide complex application into different segments.
Note that this is not necessary performance advantage over using Redux, but rather approaching its usage using plain React. Performance might be lacking due to unnecessary re-rendering that happens in below approaches, where components be rendering even though that segment is not used by that component.
Putting it plainly, this is just keeping state at <App>
level, but rather avoiding props drilling using React context.
Global state with State Hook and Context
This implementation works with functional components, and React hooks introduced. In <App>
component, state can be initiated by useState
. Here store is organized for two separate state hooks: { lang: …, color: … }
. This global store create at root level will be passed through context
provider to underlying components. Within the child component, access the context
consumer value, to read or write global store.
When creating the global store, initiated state hooks are renamed as get
and set
for ease of use. As example context.lang.get
& context.lang.set('.')
. Also note that as context was use props drilling through intermediate components was avoided. Moreover, component can include required logic.
Global state with Reducer Hook and Context
Most of React developers, are now familiar with Redux based approach for state management. Thereby similar global state can be achieved via hooks and context, through using useReducer
.
In this example context
value or global store will return {state, dispatch}
. In comparison, state
acts asmapStateToProps
while dispatch
corresponds to mapDispatchToProps
.
global-store-hook: a npm package
As seen above with simple usage of react hooks and react context, we are able to build up global store for react application. This global store can be published as npm package, so it could be used easily in application.
This simple npm package is created by me here, named global-store-hook. Here its implementation follows state hook and context hook combination discussed above. This is just an elementary package for global store, and there is plenty of room for improvement. Its used here just to demonstrate purposes.
Here store can be initiated in format of object. As an example:
const init = {
lang: 'en',
color: 'blue'
}
Afterwards this store can be easily be read as store.get('lang')
and updated as store.set('lang', 'fr')
.
Lets get started with this package by importing providers and consumer.
import {GlobalStoreProvider, GlobalStore} from 'global-store-hook';
Lets initiate provider as such as we have done in <App>
earlier:
<GlobalStoreProvider initValues={init}>
And within application, store can be easily manipulated as <MenuItem>
:
const store = GlobalStore();<p>Theme colour: {store.get('color')}</p><button onClick={() => store.set('lang', 'en')}> English </button>
As seen, global store can be easily used by this package. Lets create our previous application using this application.
As seen its pretty easy to use, but there lots of room for improvement. This package was published for demonstration purpose.
Potential improvements include:
→ Conditional re-rendering dependent on store usage
→ Support from nested store values. (Multiple context or hooks.)
If you want to make improve this package, and contribute to build more robust global store, here’s source code:
Finally, You’all should be familiar with using React hooks and context to build global store from scratch for React application.