useGlobalState: An efficient way to manage state in a React application

Dheeraj Gour
4 min readJan 2, 2023

--

State management in React: an introduction

As a React developer, you may have encountered the need to manage state in your applications. State refers to the data or variables that determine a component’s behavior and render information to the user. In a small application with a few simple components, it may be sufficient to manage state using props and component state. However, as the complexity of the application increases, managing state in this way can become cumbersome and difficult to maintain.

One way to solve this problem is by using a global state management tool, such as Redux. Redux provides a global store for storing application state and a mechanism for updating the state through actions and reducers. This can make it easier to manage state in a larger application and keep the code organized and maintainable.

In this article, we will look at how to use the useSelector and useDispatch hooks from the react-redux library to access the global store and update state in a React component. We will also create a custom hook called useGlobalState that makes it easier to access and update specific pieces of state in the global store.

Using useSelector and useDispatch

The useSelector and useDispatch hooks are provided by the react-redux library and allow you to access the global store and dispatch actions to update the state.

To use these hooks, you will need to wrap your application in a <Provider> component from react-redux and pass it the global store as a prop. Then, in your component, you can use the useSelector hook to access the state from the store and the useDispatch hook to get a reference to the dispatch function, which you can use to dispatch actions to update the state.

Here is an example of how you might use these hooks in a component:

import { useSelector, useDispatch } from 'react-redux';

const MyComponent = () => {
const count = useSelector((state) => state.counterReducer.count);
const dispatch = useDispatch();

const incrementCount = (payload) => {
dispatch({
type: 'UPDATE_COUNT',
payload
});
};

return (
<div>
<p>Count: {count}</p>
<button onClick={() => incrementCount(count + 1)}>Increment</button>
</div>
);
};

In this example, the useSelector hook is being used to access the counterReducer value from the global store. The useDispatch hook is being used to get a reference to the dispatch function, which is then used in the incrementCount function to dispatch an action with the type 'UPDATE_COUNT' to update the state.

Creating a custom hook: useGlobalState

While the useSelector and useDispatch hooks are useful for accessing and updating the global store, you may find yourself repeating the same pattern of accessing and updating specific pieces of state in multiple components. In this case, it can be helpful to create a custom hook that abstracts away this logic and makes it easier to reuse.

Here is an example of a custom hook called useGlobalState that allows you to access a specific piece of state and a corresponding dispatch function from the global reducer:

import { useSelector, useDispatch } from 'react-redux';

const useGlobalState = (key) => {
const state = useSelector((state) => state.GlobalStateReducer[key]);
const dispatch = useDispatch();

const updateState = (payload) => {
dispatch({
type: key,
payload,
});
};

return [state, updateState];
};

export default useGlobalState;

the key which is passed as an argument in this hook we will store that in other file globalStates.js like this

export const MY_STATE_KEY = 'my_state_key';

and use it in the GlobalStateReducer like this

import { MY_STATE_KEY } from './globalStates'

const initialState = {
[MY_STATE_KEY]: 0,
};

const GlobalStateReducer = (state = initialState, action) => {
switch (action.type) {
case MY_STATE_KEY:
return {
...state,
[MY_STATE_KEY]: action.payload,
};
default:
return state;
}
};

export default GlobalStateReducer;

To use this hook, you can import it into your React component and call it with the key for the piece of state you want to access. The hook will return an array with the current value of the state at that key and a function that you can call to dispatch an action to update the state.

Here’s an example of how you might use this hook in a component:

import useGlobalState from './useGlobalState';
import { MY_STATE_KEY } from './globalStates'

const MyComponent = () => {
const [count, setCount] = useGlobalState(MY_STATE_KEY);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};

In this example, the useGlobalState hook is being called with the key MY_STATE_KEY, which corresponds to a piece of state in the global reducer that is being used to track a count. The hook returns the current value of the count state and a function that can be used to increment the count.

Conclusion

State management is an important aspect of software development and can be made easier and more efficient through the use of tools like Redux and custom hooks. By centralizing and abstracting away state management logic, you can create a more maintainable and scalable application. The useSelector and useDispatch hooks from react-redux and a custom hook like useGlobalState can be useful tools for managing state in a React application.

I would suggest only using the useGlobalState hook for states with numerical or boolean values and managing all other states in separate reducers. This can help to keep your code organized and make it easier to reason about the flow of data in your application.

--

--

No responses yet