How to manage global state in a React application?
Last Updated :
24 Apr, 2025
Global state refers to data that is accessible across multiple components in a React application. Unlike the local state, which is confined to a single component, the global state can be accessed and modified from anywhere in the component tree.
In this article, we will explore the following approaches by which we can manage the global state in React.
Steps to Create React application and manage global state:
For React Context API: No additional installation is required, as it's built into React.
Step 1: Create a React application using the following command:
npx create-react-app foldername
Step 2: After creating your project folder i.e. folder name, move to it using the following command:
cd foldername
Step 3: After setting up the React environment on your system, we can start by creating an App.js file and creating a directory by the name of components.
At last, we can apply any Approach to handle Global State
Folder Structure:
Folder StructurApproach 1: Using Redux
Include dependency in project:
npm install redux react-redux
The updated dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^9.1.0",
"react-scripts": "5.0.1",
"redux": "^5.0.1",
"web-vitals": "^2.1.4"
}
Example: This example implements the above-mentioned approach.
JavaScript
// App.js
import React, { useState } from 'react';
import { Provider } from 'react-redux';
import globalStateStore from './GlobalStateStore';
import GlobalStateDisplay from './GlobalStateDisplay';
const App = () => {
const [inputValue, setInputValue] = useState('');
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const updateGlobalState = () => {
const number = parseInt(inputValue);
if (!isNaN(number)) {
store.dispatch(
{ type: 'SET_COUNT', payload: number }
);
}
};
return (
<Provider store={store}>
<div>
<input type="number" value={inputValue}
onChange={handleInputChange} />
<button onClick={updateGlobalState}>
Update Global State</button>
<GlobalStateDisplay />
</div>
</Provider>
);
}
export default App;
JavaScript
// GlobalStateDisplay.js
import React from 'react';
import { useSelector } from 'react-redux';
const GlobalStateDisplay = () => {
const count = useSelector(state => state.count);
const squaredValue = count ** 2;
return (
<div>
<p>Global State: {count}</p>
<p>Square of Global State:
{squaredValue}</p>
</div>
);
}
export default GlobalStateDisplay;
JavaScript
//GlobalStateStore.js;
import { createStore } from 'redux';
const initialState = {
count: 0
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_COUNT':
return { ...state, count: action.payload };
default:
return state;
}
};
const GlobalStateStore = createStore(reducer);
export default GlobalStateStore;
Approach 2: Using MobX
Include dependency in Project
npm install mobx mobx-react
The updated Dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"mobx": "^6.12.0",
"mobx-react": "^9.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Example: This example implements the above-mentioned approach.
JavaScript
// App.js
import React, { useState } from 'react';
import { Provider } from 'mobx-react';
import globalStateStore from './GlobalStateStore';
import GlobalStateDisplay from './GlobalStateDisplay';
const App = () => {
const [inputValue, setInputValue] = useState('');
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const updateGlobalState = () => {
const number = parseInt(inputValue);
if (!isNaN(number)) {
globalStateStore.setCount(number);
}
};
return (
<Provider store={globalStateStore}>
<div>
<input type="number" value={inputValue}
onChange={handleInputChange} />
<button onClick={updateGlobalState}>
Update Global State</button>
<GlobalStateDisplay />
</div>
</Provider>
);
}
export default App;
JavaScript
// GlobalStateDisplay.js
import React from 'react';
import { observer, inject } from 'mobx-react';
const GlobalStateDisplay = inject('store')(
observer(({ store }) => {
const count = store.count;
const squaredValue = count ** 2;
return (
<div>
<p>Global State: {count}</p>
<p>Square of Global State: {squaredValue}</p>
</div>
);
})
);
export default GlobalStateDisplay;
JavaScript
// GlobalStateStore.js
import { makeAutoObservable } from 'mobx';
class GlobalStateStore {
count = 0;
constructor() {
makeAutoObservable(this);
}
setCount(value) {
this.count = value;
}
get squaredValue() {
return this.count ** 2;
}
}
const globalStateStore = new GlobalStateStore();
export default globalStateStore;
Approach 3: Using Recoil
Include dependency in Project
npm install recoil
The updated Dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"recoil": "^0.7.7",
"web-vitals": "^2.1.4"
}
Example: This example implements the above-mentioned approach.
JavaScript
// App.js
import React, { useState } from 'react';
import { useRecoilState } from 'recoil';
import { countState } from './GlobalStateStore';
import GlobalStateDisplay from './GlobalStateDisplay';
const App = () => {
const [inputValue, setInputValue] = useState('');
const [count, setCount] = useRecoilState(countState);
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const updateGlobalState = () => {
const number = parseInt(inputValue);
if (!isNaN(number)) {
setCount(number);
setInputValue('');
}
};
return (
<div>
<input type="number" value={inputValue}
onChange={handleInputChange} />
<button onClick={updateGlobalState}>
Update Global State</button>
<GlobalStateDisplay />
</div>
);
};
export default App;
JavaScript
// GlobalStateDisplay.js
import React from 'react';
import { useRecoilValue } from 'recoil';
import { countState } from './GlobalStateStore';
const GlobalStateDisplay = () => {
const count = useRecoilValue(countState);
const squaredValue = count ** 2;
return (
<div>
<p>Global State:
{count}</p>
<p>Square of Global State:
{squaredValue}</p>
</div>
);
};
export default GlobalStateDisplay;
JavaScript
// GlobalStateStore.js
import { atom } from 'recoil';
export const countState = atom({
key: 'countState',
default: 0,
});
JavaScript
/// index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { RecoilRoot } from 'recoil';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<RecoilRoot>
<App />
</RecoilRoot>
</React.StrictMode>,
)
Approach 4: Using Zustand
Include dependency in Project
npm install zustand
The updated Dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4",
"zustand": "^4.5.2"
}
Example: This example implements the above-mentioned approach
JavaScript
// App.js
import React, { useState } from 'react';
import useGlobalState from './GlobalStateStore';
import GlobalStateDisplay from './GlobalStateDisplay';
const App = () => {
const [inputValue, setInputValue] = useState('');
const { count, setCount } = useGlobalState();
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const updateGlobalState = () => {
const number = parseInt(inputValue);
if (!isNaN(number)) {
setCount(number);
}
};
return (
<div>
<input type="number" value={inputValue}
onChange={handleInputChange} />
<button onClick={updateGlobalState}>
Update Global State</button>
<GlobalStateDisplay />
</div>
);
}
export default App;
JavaScript
// GlobalStateDisplay.js
import React from 'react';
import useGlobalState from './GlobalStateStore';
const GlobalStateDisplay = () => {
const { count } = useGlobalState();
const squaredValue = count ** 2;
return (
<div>
<p>Global State:
{count}</p>
<p>Square of Global State:
{squaredValue}</p>
</div>
);
}
export default GlobalStateDisplay;
JavaScript
// GlobalStateStore.js
import create from 'zustand';
const useGlobalState = create((set) => ({
count: 0,
setCount: (value) => set({ count: value }),
}));
export default useGlobalState;
Appraoch 5: Using XState
Include dependency in Project
npm install xstate @xstate/react
The updated Dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@xstate/react": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4",
"xstate": "^5.9.1"
}
Example: This example implements the above-mentioned approach
JavaScript
// App.js
import React, { useState } from 'react';
import useGlobalState from './GlobalStateStore';
import GlobalStateDisplay from './GlobalStateDisplay';
const App = () => {
const [inputValue, setInputValue] = useState('');
const { state, send } = useGlobalState();
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const updateGlobalState = () => {
const number = parseInt(inputValue);
if (!isNaN(number) && inputValue !== '') {
send({ type: 'SET_COUNT', value: number });
setInputValue('');
}
};
return (
<div>
<input type="number" value={inputValue}
onChange={handleInputChange} />
<button onClick={updateGlobalState}>
Update Global State</button>
<GlobalStateDisplay state={state} />
</div>
);
};
export default App;
JavaScript
// GlobalStateDisplay.js
import React from 'react';
const GlobalStateDisplay = ({ state }) => {
const count = state.context.count;
const squaredValue = count * count;
console.log(squaredValue);
return (
<div>
<p>Global State: {count}</p>
<p>Square of Global State: {squaredValue}</p>
</div>
);
};
export default GlobalStateDisplay;
JavaScript
// GlobalStateStore.js
import { createMachine, assign } from 'xstate';
import { useMachine } from '@xstate/react';
const globalStateMachine = createMachine({
id: 'globalState',
initial: 'idle',
context: {
count: 0,
},
states: {
idle: {
on: {
SET_COUNT: {
actions: assign({
count: (_, event) => event.value,
}),
},
},
},
final: {
type: 'final',
},
},
});
const useGlobalState = () => {
const [state, send] = useMachine(globalStateMachine);
return { state, send };
};
export default useGlobalState;
Output(Same for all Approaches):
calculating square of a number from Global State
Similar Reads
How to Normalize State in Redux Applications ?
In Redux applications, efficient state management is essential for scalability and maintainability. Normalization is a technique used to restructure complex state data into a more organized format, improving performance and simplifying state manipulation. This article covers the concept of normaliza
3 min read
How to set up the Provider Component in a React application ?
In React applications, the Provider component is often used in conjunction with context to provide data to components deep down in the component tree without having to explicitly pass props through every level of the tree. Prerequisites:JavaScriptReactNode & NPMSteps to Create React Application:
3 min read
How does React Router handle navigation in a React application?
React Router is a standard library for routing in React. It enables the navigation among views of various components in a React Application, allows changing the browser URL, and keeps the UI in sync with the URL. Let us create a simple application to React to understand how the React Router works Re
3 min read
How to check App State in React Native ?
React Native is an open-source UI software framework created by Meta Platforms, Inc. It is used to develop applications for Android, Android TV, iOS, macOS, tvOS, Web, Windows, and UWP by enabling developers to use the React framework along with native platform capabilities.In this article, we will
2 min read
How to Organize Large React Application and Make it Scalable ?
React is a declarative, efficient, and flexible JavaScript library for building user interfaces. Itâs âVâ in MVC. ReactJS is an open-source, component-based front-end library responsible only for the view layer of the application. It is essential to organize a large react app so that it can be easil
4 min read
How to Use Flux to Manage State in ReactJS?
State management in ReactJS is important for building dynamic and responsive applications. Flux, an architecture for managing state, provides a structured approach to handle data flow and state changes efficiently in React applications. In this article, we will explore the Flux to Manage State in Re
5 min read
How to Manage User Sessions and Tokens in Redux Applications?
This project is designed to provide a basic user authentication system entirely on the client side using React and Redux, allowing users to login, register, and logout. Authentication actions and state management are managed locally, with user data stored in the browser's local storage. ApproachProj
4 min read
How to locally manage component's state in ReactJS ?
Any component in React JS majorly depends on its props and state to manage data. A component's state is private to it and is responsible for governing its behavior throughout its life. A state is nothing but a structure that records any data changes in a react application. It can be used for storing
2 min read
How to Manage State in Remix?
Managing the state in Remix is one of the basics of making interactive applications. State management in Remix happens both on the client and the server, stitching server-side rendering together with client-side state management. Remix gives flexibility to handle the server-side or client-side state
6 min read
State Management in React â Hooks, Context API and Redux
State management is a critical concept when working with React. React components can hold local state, but as applications grow, managing state across multiple components can become complex. To help manage this complexity, React provides several tools: Hooks, Context API, and Redux. Here are some fe
6 min read