Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
Creating Context is like setting up a radio station - you're establishing a broadcast channel that will carry specific type of data throughout your application.
Create a dedicated file for your Context. This keeps your Context logic organized and reusable across your application.
Best Practice
Create Context files in a dedicated `contexts/` folder for better organization.
Define the structure and default values for your Context. This provides type safety and fallback values.
Type Safety
Define the complete shape including functions to ensure consistent API across your app.
Create a custom hook to consume your Context safely. This provides better error handling and developer experience.
Safety First
Custom hooks provide clear error messages and prevent undefined Context usage.
Create a Provider component that manages the state and provides values to the Context consumers.
Encapsulation
The Provider encapsulates state logic and provides a clean API to consumers.
Complete user authentication Context with login/logout functionality (no persistence in playground)
// contexts/AuthContext.js
import React, { createContext, useContext, useState, useEffect } from 'react';
// Define authentication context shape
const AuthContext = createContext({
user: null,
isAuthenticated: false,
login: () => {},
logout: () => {},
loading: false,
});
// Custom hook for auth consumption
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}
// Authentication provider component
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
// Login function
const login = async (email, password) => {
setLoading(true);
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 1000));
const userData = {
id: 1,
name: 'John Doe',
email: email,
avatar: '👤'
};
setUser(userData);
} catch (error) {
console.error('Login failed:', error);
} finally {
setLoading(false);
}
};
// Logout function
const logout = () => {
setUser(null);
};
const value = {
user,
isAuthenticated: !!user,
login,
logout,
loading,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
export default AuthContext;
// Example App component using the AuthContext
function App() {
const { user, isAuthenticated, login, logout, loading } = useAuth();
if (loading) {
return <div className="app"><h1>Loading...</h1></div>;
}
if (!isAuthenticated) {
return <LoginForm onLogin={login} />;
}
return <Dashboard user={user} onLogout={logout} />;
}
// Login form component
function LoginForm({ onLogin }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setIsLoading(true);
await onLogin(email, password);
setIsLoading(false);
};
return (
<div className="app">
<div className="login-form">
<h1>🔐 Login</h1>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label>Email:</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="john@example.com"
required
/>
</div>
<div className="form-group">
<label>Password:</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="••••••••"
required
/>
</div>
<button type="submit" disabled={isLoading} className="login-btn">
{isLoading ? 'Logging in...' : 'Login'}
</button>
</form>
<p className="hint">Hint: Use any email and password</p>
</div>
</div>
);
}
// Dashboard component
function Dashboard({ user, onLogout }) {
return (
<div className="app">
<div className="dashboard">
<div className="user-info">
<div className="avatar">{user.avatar}</div>
<div>
<h2>Welcome, {user.name}!</h2>
<p>{user.email}</p>
</div>
</div>
<div className="actions">
<button className="logout-btn" onClick={onLogout}>
Logout
</button>
</div>
</div>
</div>
);
}
// ReactDOM integration
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<AuthProvider>
<App />
</AuthProvider>
);Loading preview...
After creating your Context and Provider, you need to integrate them with ReactDOM to render your application with the Context available throughout the component tree.