Global State Management with React Hooks and Context

If you are using React.js, you are probably familiar with Redux. Redux has been the go-to for global state management with javascript  projects. However, Redux introduces more complexities with actions, reducers and a store, requiring a lot of extra code for setting up a global state. Luckily the good people over at React saw that a lean global state management  tool was something that React needed and with React  16.3 they introduced the context API. Context provides a way to pass data through the component tree without having to pass props down manually at every level, managing state in multiple components that are not directly connected. Enough talking about it. Let me show you with some code. Let’s create a simple app to demonstrate how to set up a store that gives us access to the global state anywhere in the app.

Let’s open a React project in your favorite code editor and create a javaScript file called Store.js in your src folder.  

First thing we will do is create a context. To create a context we will use the createContext method from React, which takes our initialState object and returns a provider and consumer component. For this application we will just return the Provider.

The Provider component is what makes the state available to all children components no matter how deeply nested they are. 

Now we will create a StateProvider component with the useReducer hook, this takes two values as arguments, a reducer function and an initial state and then returns a new state. Then we pass the Provider component the value dispatch and state as a prop.

Our completed store component will look like this.

Now we wrap the app.js with the StateProvider and we have access to that context with the useContext React method anywhere in the app. If we pass useContext the store we exported it returns state and dispatch. Dispatch allows you to call an action in the reducer and update the state.  State is the context you created.

To update the state with the SET_USER action from our useReducer function, we will pass dispatch the type SET_USER and the user will be updated with the payload you passed to the useReducer function. 

Context is a lean way to manage state globally without having too much extra setup or dependencies. However, I can see where it has its pitfalls and could lead to performance issues from too many rerenders. If your state is frequently updated, React Context may not be as effective as Redux. If you have data that undergoes lower frequency updates such as authentication or preferred language, React Context may be the best option for  you.