React has revolutionized the way we build user interfaces, especially with its component-based architecture. However, as applications grow, managing state across various components can become substantially tricky. This is where context-based state management comes into play. Using the Context API, we can share state across our application without having to rely on prop drilling.
In this blog, we will build a simple context-based state management system, demonstrating how to manage global state in our React app smoothly.
Setting Up Our Application
To get started, let's set up a new React application. If you don't have create-react-app installed, you can do so by running:
npx create-react-app react-context-example cd react-context-example
Once created, navigate to the project folder.
Creating Our Context
Inside the src directory, let's create a new folder named context. Inside this folder, create a file named AppContext.js. This file will hold our context and the provider component that will wrap our application.
// src/context/AppContext.js import React, { createContext, useState } from 'react'; // Create a Context for the app export const AppContext = createContext(); // Create a Provider component export const AppProvider = ({ children }) => { const [state, setState] = useState({ user: null, theme: 'light', }); const login = (user) => { setState((prevState) => ({ ...prevState, user })); }; const logout = () => { setState((prevState) => ({ ...prevState, user: null })); }; const toggleTheme = () => { setState((prevState) => ({ ...prevState, theme: prevState.theme === 'light' ? 'dark' : 'light', })); }; return ( <AppContext.Provider value={{ state, login, logout, toggleTheme }}> {children} </AppContext.Provider> ); };
Breakdown of the Provider
- Creating the context: We use
createContextto create a new context, which will hold our global state. - Setting up the provider: The
AppProvidercomponent holds a piece of state using theuseStatehook. This state containsuserandtheme. - Login and Logout functions: We define functions to modify the user state.
- Theme toggle: We present a function to toggle between light and dark themes.
Wrapping Our App with the Provider
Now that we have our context set up, we need to wrap our application with the AppProvider. Update the src/index.js file:
// src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import { AppProvider } from './context/AppContext'; ReactDOM.render( <React.StrictMode> <AppProvider> <App /> </AppProvider> </React.StrictMode>, document.getElementById('root') );
Consuming Context in Components
Now we can use the context in any component. Let's create a simple user component that can log in, log out, and toggle the theme.
First, create a new component called User.js inside the src directory:
// src/User.js import React, { useContext } from 'react'; import { AppContext } from './context/AppContext'; const User = () => { const { state, login, logout, toggleTheme } = useContext(AppContext); return ( <div style={{ background: state.theme === 'dark' ? '#333' : '#fff', color: state.theme === 'dark' ? '#fff' : '#000' }}> <h1>{state.user ? `Hello, ${state.user}` : 'Please, log in.'}</h1> <button onClick={() => (state.user ? logout() : login('John'))}> {state.user ? 'Logout' : 'Login'} </button> <button onClick={toggleTheme}>Toggle Theme</button> </div> ); }; export default User;
Breakdown of the User Component
- Context consumption: We use
useContextto consume ourAppContext. - Dynamic rendering: We dynamically change the heading and button based on the user's log-in state.
- Styling based on theme: The background and text color change based on the
themestate.
Next Steps
Finally, we need to incorporate our User component into the main App.js:
// src/App.js import React from 'react'; import User from './User'; const App = () => { return ( <div className="App"> <User /> </div> ); }; export default App;
Now save your changes and run your app using npm start. You should see a simple interface that allows you to log in and out, as well as toggle between light and dark themes.
With this setup, you have a fully functional context-based state management system using React's Context API. This method is light on overhead and provides a clear structure for managing and distributing state throughout your components. Whether you're building a small single-page app or a more complex enterprise solution, this technique is a fantastic way to keep your state organized and maintainable.
