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
createContext
to create a new context, which will hold our global state. - Setting up the provider: The
AppProvider
component holds a piece of state using theuseState
hook. This state containsuser
andtheme
. - 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
useContext
to 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
theme
state.
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.