React JS Course

To avoid prop drilling, we need to make use of Context API in class components and useContext in functional components.
Now lets see useContext.
- Accepts a context object(the value returned from createContext).
- Returns the current context value for that context.
- current context value is determined by value prop of the nearest <MyContext.Provider> above the calling component in the tree.
For example,
const themes = { light: { foreground: "#000000", background: "#eeeeee", }, dark: { foreground: "#ffffff", background: "#222222", }, }; const ThemeContext = React.createContext(themes.light); function App() { return ( <ThemeContext.Provider value={themes.dark}> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { const theme = useContext(ThemeContext); return ( <button style={{ background: theme.background, color: theme.foreground }}> I am styled by theme context! </button> ); }
Let's consider a more realistic example using useContext in a scenario where you might have an authentication system. We'll create a context to manage the authentication status and user information across your application.
Create an Authentication Context
import React, { createContext, useState, useContext } from 'react'; // Create the Authentication Context const AuthContext = createContext(); export const useAuth = () => useContext(AuthContext); const AuthProvider = ({ children }) => { const [isAuthenticated, setIsAuthenticated] = useState(false); const [user, setUser] = useState(null); const login = (userInfo) => { setIsAuthenticated(true); setUser(userInfo); }; const logout = () => { setIsAuthenticated(false); setUser(null); }; return ( <AuthContext.Provider value={{ isAuthenticated, user, login, logout }}> {children} </AuthContext.Provider> ); }; export default AuthProvider;
Create Components to Use Authentication Context
Login Component
import React, { useState } from 'react'; import { useAuth } from './AuthProvider'; const Login = () => { const { login } = useAuth(); const [username, setUsername] = useState(''); const handleLogin = () => { login({ name: username }); setUsername(''); }; return ( <div> <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Enter your username" /> <button onClick={handleLogin}>Login</button> </div> ); }; export default Login;
Logout Component
import React from 'react'; import { useAuth } from './AuthProvider'; const Logout = () => { const { logout } = useAuth(); return <button onClick={logout}>Logout</button>; }; export default Logout;
UserProfile Component
import React from 'react'; import { useAuth } from './AuthProvider'; const UserProfile = () => { const { isAuthenticated, user } = useAuth(); return ( <div> {isAuthenticated ? ( <div> <h1>Welcome, {user.name}!</h1> <Logout /> </div> ) : ( <p>Please log in.</p> )} </div> ); }; export default UserProfile;
Finally, wrap our application with the AuthProvider to make the authentication context available to your components.
import React from 'react'; import ReactDOM from 'react-dom'; import AuthProvider from './AuthProvider'; import Login from './Login'; import UserProfile from './UserProfile'; const App = () => ( <AuthProvider> <div> <UserProfile /> <Login /> </div> </AuthProvider> ); ReactDOM.render(<App />, document.getElementById('root'));
This setup allows you to manage authentication state across your application efficiently, ensuring that components can easily check if a user is logged in and manage user sessions.