π― What Are Multiple Returns? (Simple Analogy)
Imagine you're a security guard at a building entrance:
SINGLE RETURN (What you learned before):
Everyone goes through the same door, same process
βββββββββββββββββββββββββββββββββββββββββββ
βΒ π’ BUILDING ENTRANCEΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ 1. Check IDΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ 2. Check temperatureΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ 3. Check bagΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ 4. Give badgeΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ 5. Let inΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Problem: If someone has no ID,Β Β Β Β Β Β Β Β Β β
βΒ you still do steps 2-5 beforeΒ Β Β Β Β Β Β Β Β β
βΒ telling them to leave!Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ In React:Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ function Entrance() {Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β return (Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β <div>Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β {hasId ? <LetIn /> : <GoAway />} β
βΒ Β Β Β Β Β Β {/* Lots of other checks */}Β Β Β Β Β β
βΒ Β Β Β Β </div>Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β );Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ }Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βββββββββββββββββββββββββββββββββββββββββββ
EARLY RETURN (New technique):
Send people away immediately if they don't qualify
βββββββββββββββββββββββββββββββββββββββββββ
βΒ π’ BUILDING ENTRANCEΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ NO ID? β "Sorry, you can't enter"Β Β Β Β Β β
βΒ Β Β β GO AWAY (Early return!)Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ NO TEMP CHECK? β "Go to nurse"Β Β Β Β Β Β Β Β β
βΒ Β Β β GO AWAY (Another early return!)Β Β Β β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Everything good? β Continue processΒ Β β
βΒ Β Β β NORMAL RETURNΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ In React:Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ function Entrance() {Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β if (!hasId) return <GoAway />;Β Β Β Β Β Β Β β
βΒ Β Β if (!tempCheck) return <GoToNurse />; β
βΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β return (Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β <div>Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β <LetIn />Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β Β Β Β Β {/* Only runs if passed checks */}β
βΒ Β Β Β Β </div>Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ Β Β );Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βΒ }Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β β
βββββββββββββββββββββββββββββββββββββββββββ
KEY INSIGHT:
Early return = "Stop and exit immediately"
Normal return = "Continue to the end"
β οΈ The Big Problem: "Why Can't I Use If-Else in JSX?"
// ==========================================
// THE "IF-ELSE INSIDE JSX" TRAP (Review)
// ==========================================
// β WRONG: Trying if-else inside JSX curly braces
function BadIfElseInJsx() {
const isOpen = false;
return (
<footer>
{
if (!isOpen) { // β ERROR! "Unexpected token"
return <p>Closed</p>; // Statements don't work in JSX!
}
}
</footer>
);
}
// Remember: JSX {} only accepts EXPRESSIONS, not STATEMENTS
// if/else is a STATEMENT (does action, returns nothing)
// Ternary is an EXPRESSION (returns value)
// ==========================================
// THE "MESSY TERNARY" TRAP
// ==========================================
// β CONFUSING: Complex ternary with many conditions
function MessyTernary() {
const { soldOut, price, name, ingredients } = props.pizzaObj;
return (
<li className="pizza">
{soldOut ? (
<div className="sold-out">
<p>{name} - SOLD OUT</p>
</div>
) : (
<>
<img src={props.photoName} alt={name} />
<div>
<h3>{name}</h3>
<p>{ingredients}</p>
<span>${price}</span>
</div>
</>
)}
</li>
);
}
// Problem: Entire component structure changes based on condition
// Ternary becomes huge and hard to read!
// β
CLEAN: Early return for completely different UI
function CleanEarlyReturn() {
const { soldOut, price, name, ingredients, photoName } = props.pizzaObj;
// Early return: Completely different component when sold out
if (soldOut) {
return (
<li className="pizza sold-out">
<p>{name} - SOLD OUT</p>
</li>
);
}
// Normal return: Standard pizza display
return (
<li className="pizza">
<img src={photoName} alt={name} />
<div>
<h3>{name}</h3>
<p>{ingredients}</p>
<span>${price}</span>
</div>
</li>
);
}
// Visual comparison:
// Messy Ternary: Clean Early Return:
// One return with Two returns, clean separation
// huge ternary inside
// β β
// Hard to read Easy to understand
// Mixed logic Separated concerns
π Complete Basic Examples
Create file: react-early-returns.js
// ==========================================
// EARLY RETURNS - Complete Guide
// ==========================================
/*
EARLY RETURN PATTERN:
βββββββββββββββββββββββββββββββββββββββββββ
β function Component() { β
β if (condition1) return <A />; β
β if (condition2) return <B />; β
β β
β // Only reaches here if all β
β // conditions above were false β
β return <Default />; β
β } β
β β
β Like a bouncer: β
β β’ No ID? β Leave immediately β
β β’ Too drunk? β Leave immediately β
β β’ All good? β Come in β
βββββββββββββββββββββββββββββββββββββββββββ
*/
// ==========================================
// EXAMPLE 1: Restaurant Footer (From Your Text)
// ==========================================
function Footer() {
const hour = new Date().getHours();
const isOpen = hour >= 12 && hour <= 22;
// EARLY RETURN: Show closed message immediately
if (!isOpen) {
return (
<footer className="footer">
<p>We're happy to welcome you between 12:00 and 22:00.</p>
</footer>
);
}
// NORMAL RETURN: Only reached if restaurant IS open
return (
<footer className="footer">
<div className="order">
<p>We're open until 22:00. Come visit us or order online.</p>
<button className="btn">Order</button>
</div>
</footer>
);
}
// Visual Flow:
// Time: 11 PM (23:00)
// isOpen = false
// β
// if (!isOpen) β TRUE
// β
// return <ClosedFooter />
// β
// Component exits! Normal return never runs!
// Time: 3 PM (15:00)
// isOpen = true
// β
// if (!isOpen) β FALSE
// β
// Skip early return, continue...
// β
// return <OpenFooter />
// β
// Shows open message + button
// ==========================================
// EXAMPLE 2: Pizza Sold Out (From Your Text)
// ==========================================
function Pizza({ pizzaObj }) {
// EARLY RETURN: Don't show sold out pizzas
if (pizzaObj.soldOut) {
return null; // Return NOTHING (component disappears!)
}
// NORMAL RETURN: Only for available pizzas
return (
<li className="pizza">
<img src={pizzaObj.photoName} alt={pizzaObj.name} />
<div>
<h3>{pizzaObj.name}</h3>
<p>{pizzaObj.ingredients}</p>
<span>${pizzaObj.price}</span>
</div>
</li>
);
}
// What happens:
// Pizza Salamino (soldOut: true)
// β
// if (pizzaObj.soldOut) β TRUE
// β
// return null
// β
// React renders NOTHING (empty)
// Pizza Margherita (soldOut: false)
// β
// if (pizzaObj.soldOut) β FALSE
// β
// Continue to normal return...
// β
// Shows full pizza card!
// ==========================================
// EXAMPLE 3: Loading & Error States
// ==========================================
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetchUser(userId)
.then(data => {
setUser(data);
setIsLoading(false);
})
.catch(err => {
setError(err);
setIsLoading(false);
});
}, [userId]);
// EARLY RETURN 1: Still loading
if (isLoading) {
return (
<div className="loading">
<div className="spinner">β³</div>
<p>Loading user data...</p>
</div>
);
}
// EARLY RETURN 2: Error occurred
if (error) {
return (
<div className="error">
<p>β Failed to load user</p>
<p>{error.message}</p>
<button onClick={() => window.location.reload()}>
Retry
</button>
</div>
);
}
// EARLY RETURN 3: No user found
if (!user) {
return (
<div className="empty">
<p>User not found</p>
</div>
);
}
// NORMAL RETURN: Only reached if all above passed
return (
<div className="user-profile">
<img src={user.avatar} alt={user.name} />
<h1>{user.name}</h1>
<p>{user.bio}</p>
<button>Edit Profile</button>
</div>
);
}
// Flow:
// isLoading = true
// β
// return <Loading />
// [STOP - other returns never run]
// isLoading = false, error = Error
// β
// Skip loading check...
// β
// return <Error />
// [STOP]
// isLoading = false, error = null, user = null
// β
// Skip loading check...
// Skip error check...
// β
// return <NotFound />
// [STOP]
// isLoading = false, error = null, user = {...}
// β
// Skip loading check...
// Skip error check...
// Skip null check...
// β
// return <Profile />
// ==========================================
// EXAMPLE 4: Authentication Guard
// ==========================================
function AdminDashboard({ user }) {
// EARLY RETURN 1: Not logged in
if (!user) {
return <LoginPrompt />;
}
// EARLY RETURN 2: Logged in but not admin
if (!user.isAdmin) {
return (
<div className="access-denied">
<h1>π« Access Denied</h1>
<p>You need admin privileges to view this page.</p>
<p>Your role: {user.role}</p>
</div>
);
}
// EARLY RETURN 3: Admin but account expired
if (user.isExpired) {
return (
<div className="account-expired">
<h1>β οΈ Account Expired</h1>
<p>Please renew your admin subscription.</p>
<button>Renew Now</button>
</div>
);
}
// NORMAL RETURN: Only for valid admins
return (
<div className="admin-dashboard">
<h1>Welcome, Admin {user.name}!</h1>
<AdminSidebar />
<AdminStats />
<UserManagementTable />
</div>
);
}
// ==========================================
// EXAMPLE 5: Form Validation
// ==========================================
function RegistrationForm({ onSubmit }) {
const [step, setStep] = useState(1);
const [formData, setFormData] = useState({});
// Early return for multi-step form
if (step === 1) {
return (
<Step1Form
data={formData}
onNext={(data) => {
setFormData({...formData, ...data});
setStep(2);
}}
/>
);
}
if (step === 2) {
return (
<Step2Form
data={formData}
onNext={(data) => {
setFormData({...formData, ...data});
setStep(3);
}}
onBack={() => setStep(1)}
/>
);
}
if (step === 3) {
return (
<ReviewForm
data={formData}
onSubmit={() => onSubmit(formData)}
onBack={() => setStep(2)}
/>
);
}
// Fallback (shouldn't reach here)
return <p>Unknown step</p>;
}
π React Usage Examples (Full Visual Guide!)
Complete React File: EarlyReturnsMasterClass.jsx
import React, { useState, useEffect } from 'react';
// ==========================================
// INTERACTIVE EARLY RETURNS DEMO
// ==========================================
function EarlyReturnsMasterClass() {
const [activeTab, setActiveTab] = useState('basic');
const demos = {
basic: { title: 'Basic Early Return', component: <BasicEarlyReturnDemo /> },
loading: { title: 'Loading States', component: <LoadingStatesDemo /> },
auth: { title: 'Authentication', component: <AuthDemo /> },
comparison: { title: 'vs Ternary/&&', component: <ComparisonDemo /> }
};
return (
<div style={{ maxWidth: '900px', margin: '0 auto', padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<header style={{ background: '#e9c46a', color: '#264653', padding: '30px', borderRadius: '10px', marginBottom: '30px' }}>
<h1 style={{ margin: 0 }}>π Early Returns Master Class</h1>
<p style={{ margin: '10px 0 0 0', opacity: 0.9 }}>Multiple Returns for Clean Conditional Rendering</p>
</header>
<nav style={{ display: 'flex', gap: '10px', marginBottom: '30px', flexWrap: 'wrap' }}>
{Object.entries(demos).map(([key, { title }]) => (
<button
key={key}
onClick={() => setActiveTab(key)}
style={{
padding: '12px 24px',
fontSize: '16px',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
backgroundColor: activeTab === key ? '#264653' : '#e0e0e0',
color: activeTab === key ? 'white' : '#333',
fontWeight: activeTab === key ? 'bold' : 'normal'
}}
>
{title}
</button>
))}
</nav>
<main style={{ background: '#f8f9fa', padding: '30px', borderRadius: '10px', minHeight: '400px' }}>
{demos[activeTab].component}
</main>
</div>
);
}
// ==========================================
// DEMO 1: Basic Early Return
// ==========================================
function BasicEarlyReturnDemo() {
const [isOpen, setIsOpen] = useState(true);
const [showSoldOut, setShowSoldOut] = useState(false);
return (
<div>
<h2>How Early Returns Work</h2>
<div style={{ marginBottom: '20px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
<button
onClick={() => setIsOpen(!isOpen)}
style={{ padding: '10px 20px', background: isOpen ? '#4caf50' : '#f44336', color: 'white', border: 'none', borderRadius: '5px' }}
>
Restaurant: {isOpen ? 'OPEN' : 'CLOSED'}
</button>
<button
onClick={() => setShowSoldOut(!showSoldOut)}
style={{ padding: '10px 20px', background: showSoldOut ? '#ff9800' : '#2196f3', color: 'white', border: 'none', borderRadius: '5px' }}
>
Pizza: {showSoldOut ? 'SOLD OUT' : 'AVAILABLE'}
</button>
</div>
<div style={{ display: 'grid', gap: '20px', gridTemplateColumns: '1fr 1fr' }}>
{/* Restaurant Example */}
<div style={{ padding: '20px', background: 'white', borderRadius: '8px', border: '2px solid #e0e0e0' }}>
<h3>πͺ Restaurant Footer</h3>
<pre style={{ background: '#1e1e1e', color: '#d4d4d4', padding: '15px', borderRadius: '4px', fontSize: '12px', overflow: 'auto' }}>
{`function Footer() {
// EARLY RETURN
if (!isOpen) {
return (
<footer>
<p>Closed. Open 12-22h</p>
</footer>
);
}
// NORMAL RETURN
return (
<footer>
<p>We're open!</p>
<button>Order</button>
</footer>
);
}`}
</pre>
<div style={{ marginTop: '15px', padding: '15px', background: '#f5f5f5', borderRadius: '4px' }}>
<h4>Result:</h4>
<RestaurantFooter isOpen={isOpen} />
</div>
</div>
{/* Pizza Example */}
<div style={{ padding: '20px', background: 'white', borderRadius: '8px', border: '2px solid #e0e0e0' }}>
<h3>π Pizza Card</h3>
<pre style={{ background: '#1e1e1e', color: '#d4d4d4', padding: '15px', borderRadius: '4px', fontSize: '12px', overflow: 'auto' }}>
{`function Pizza({ soldOut }) {
// EARLY RETURN
if (soldOut) {
return null; // Disappears!
}
// NORMAL RETURN
return (
<div className="pizza">
<h3>Pepperoni</h3>
<p>$12</p>
</div>
);
}`}
</pre>
<div style={{ marginTop: '15px', padding: '15px', background: '#f5f5f5', borderRadius: '4px' }}>
<h4>Result:</h4>
<PizzaCard soldOut={showSoldOut} />
</div>
</div>
</div>
</div>
);
}
function RestaurantFooter({ isOpen }) {
if (!isOpen) {
return (
<footer style={{ padding: '15px', background: '#ffebee', borderRadius: '8px', color: '#c62828' }}>
<p style={{ margin: 0 }}>π We're happy to welcome you between 12:00 and 22:00.</p>
</footer>
);
}
return (
<footer style={{ padding: '15px', background: '#e8f5e9', borderRadius: '8px' }}>
<p style={{ margin: '0 0 10px 0', color: '#2e7d32' }}>π’ We're open until 22:00!</p>
<button style={{ padding: '8px 16px', background: '#4caf50', color: 'white', border: 'none', borderRadius: '4px' }}>
Order Now
</button>
</footer>
);
}
function PizzaCard({ soldOut }) {
if (soldOut) {
return (
<div style={{ padding: '15px', background: '#fff3e0', borderRadius: '8px', color: '#e65100', textAlign: 'center' }}>
<p style={{ margin: 0 }}>π Pepperoni - SOLD OUT</p>
</div>
);
}
return (
<div style={{ padding: '15px', background: 'white', borderRadius: '8px', border: '2px solid #e0e0e0' }}>
<h4 style={{ margin: '0 0 10px 0' }}>π Pepperoni</h4>
<p style={{ margin: '0 0 10px 0', color: '#666' }}>Tomato, mozzarella, pepperoni</p>
<span style={{ fontWeight: 'bold', color: '#2a9d8f', fontSize: '18px' }}>$12</span>
</div>
);
}
// ==========================================
// DEMO 2: Loading States with Early Returns
// ==========================================
function LoadingStatesDemo() {
const [status, setStatus] = useState('idle'); // idle, loading, error, success
return (
<div>
<h2>Loading States Pattern</h2>
<div style={{ marginBottom: '20px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
{['idle', 'loading', 'error', 'success'].map(s => (
<button
key={s}
onClick={() => setStatus(s)}
style={{
padding: '10px 20px',
background: status === s ? '#264653' : '#e0e0e0',
color: status === s ? 'white' : '#333',
border: 'none',
borderRadius: '5px',
textTransform: 'capitalize'
}}
>
{s}
</button>
))}
</div>
<div style={{ padding: '20px', background: 'white', borderRadius: '8px', border: '2px solid #e0e0e0' }}>
<h3>Code:</h3>
<pre style={{ background: '#1e1e1e', color: '#d4d4d4', padding: '15px', borderRadius: '4px', fontSize: '13px', overflow: 'auto' }}>
{`function DataDisplay({ status, data, error }) {
// Early return: Loading
if (status === 'loading') {
return <div className="spinner">Loading...</div>;
}
// Early return: Error
if (status === 'error') {
return <div className="error">Error: {error}</div>;
}
// Early return: No data
if (!data || data.length === 0) {
return <div className="empty">No data found</div>;
}
// Normal return: Show data
return (
<ul>
{data.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
}`}
</pre>
<h3 style={{ marginTop: '20px' }}>Result:</h3>
<DataDisplay status={status} />
</div>
</div>
);
}
function DataDisplay({ status }) {
// Simulate data
const data = status === 'success' ? [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
] : [];
const error = { message: 'Failed to fetch data' };
// EARLY RETURN 1: Loading
if (status === 'loading') {
return (
<div style={{ textAlign: 'center', padding: '40px' }}>
<div style={{ fontSize: '40px', animation: 'spin 1s linear infinite' }}>β³</div>
<p>Loading data...</p>
</div>
);
}
// EARLY RETURN 2: Error
if (status === 'error') {
return (
<div style={{ padding: '20px', background: '#ffebee', borderRadius: '8px', color: '#c62828' }}>
<h4>β Error</h4>
<p>{error.message}</p>
<button style={{ padding: '8px 16px', background: '#f44336', color: 'white', border: 'none', borderRadius: '4px' }}>
Retry
</button>
</div>
);
}
// EARLY RETURN 3: Empty data
if (status === 'idle' || data.length === 0) {
return (
<div style={{ textAlign: 'center', padding: '40px', color: '#999' }}>
<p>No data to display</p>
<p style={{ fontSize: '14px' }}>Click "Success" to load data</p>
</div>
);
}
// NORMAL RETURN: Show data
return (
<ul style={{ listStyle: 'none', padding: 0 }}>
{data.map(item => (
<li key={item.id} style={{ padding: '10px', background: '#e8f5e9', marginBottom: '5px', borderRadius: '4px' }}>
β {item.name}
</li>
))}
</ul>
);
}
// ==========================================
// DEMO 3: Authentication Flow
// ==========================================
function AuthDemo() {
const [authState, setAuthState] = useState('loggedOut'); // loggedOut, user, admin, expired
return (
<div>
<h2>Authentication with Early Returns</h2>
<div style={{ marginBottom: '20px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
{[
{ key: 'loggedOut', label: 'Logged Out' },
{ key: 'user', label: 'Regular User' },
{ key: 'admin', label: 'Admin' },
{ key: 'expired', label: 'Expired Admin' }
].map(({ key, label }) => (
<button
key={key}
onClick={() => setAuthState(key)}
style={{
padding: '10px 20px',
background: authState === key ? '#264653' : '#e0e0e0',
color: authState === key ? 'white' : '#333',
border: 'none',
borderRadius: '5px'
}}
>
{label}
</button>
))}
</div>
<div style={{ padding: '20px', background: 'white', borderRadius: '8px', border: '2px solid #e0e0e0' }}>
<AuthScreen authState={authState} />
</div>
</div>
);
}
function AuthScreen({ authState }) {
// Simulate user object based on state
const user = authState === 'loggedOut' ? null : {
name: 'Alice',
role: authState === 'admin' || authState === 'expired' ? 'admin' : 'user',
isExpired: authState === 'expired'
};
// EARLY RETURN 1: Not logged in
if (!user) {
return (
<div style={{ textAlign: 'center', padding: '40px' }}>
<h3>π Welcome</h3>
<p>Please log in to access the dashboard</p>
<button style={{ padding: '10px 20px', background: '#4caf50', color: 'white', border: 'none', borderRadius: '5px' }}>
Login
</button>
</div>
);
}
// EARLY RETURN 2: Expired account
if (user.isExpired) {
return (
<div style={{ textAlign: 'center', padding: '40px', background: '#fff3e0', borderRadius: '8px' }}>
<h3>β οΈ Account Expired</h3>
<p>Your admin subscription has expired</p>
<button style={{ padding: '10px 20px', background: '#ff9800', color: 'white', border: 'none', borderRadius: '5px' }}>
Renew Subscription
</button>
</div>
);
}
// EARLY RETURN 3: Regular user (not admin)
if (user.role !== 'admin') {
return (
<div style={{ padding: '20px' }}>
<h3>π€ User Dashboard</h3>
<p>Welcome, {user.name}!</p>
<div style={{ padding: '15px', background: '#f5f5f5', borderRadius: '8px', marginTop: '10px' }}>
<p>Your account features:</p>
<ul>
<li>View profile</li>
<li>Edit settings</li>
</ul>
</div>
</div>
);
}
// NORMAL RETURN: Admin with valid account
return (
<div style={{ padding: '20px' }}>
<h3>π Admin Dashboard</h3>
<p>Welcome back, Admin {user.name}!</p>
<div style={{ display: 'grid', gap: '10px', marginTop: '15px' }}>
<div style={{ padding: '15px', background: '#e8f5e9', borderRadius: '8px' }}>
<h4 style={{ margin: '0 0 10px 0' }}>π Statistics</h4>
<p style={{ margin: 0 }}>Users: 1,234 | Revenue: $5,678</p>
</div>
<div style={{ padding: '15px', background: '#e3f2fd', borderRadius: '8px' }}>
<h4 style={{ margin: '0 0 10px 0' }}>βοΈ Management</h4>
<button style={{ marginRight: '10px', padding: '8px 16px' }}>Users</button>
<button style={{ padding: '8px 16px' }}>Settings</button>
</div>
</div>
</div>
);
}
// ==========================================
// DEMO 4: Comparison with Ternary/&&
// ==========================================
function ComparisonDemo() {
const [condition, setCondition] = useState('true');
return (
<div>
<h2>Early Return vs Other Methods</h2>
<div style={{ marginBottom: '20px', display: 'flex', gap: '10px' }}>
<button onClick={() => setCondition('true')} style={{ padding: '10px 20px', background: condition === 'true' ? '#4caf50' : '#e0e0e0', color: condition === 'true' ? 'white' : '#333', border: 'none', borderRadius: '5px' }}>
Condition: TRUE
</button>
<button onClick={() => setCondition('false')} style={{ padding: '10px 20px', background: condition === 'false' ? '#f44336' : '#e0e0e0', color: condition === 'false' ? 'white' : '#333', border: 'none', borderRadius: '5px' }}>
Condition: FALSE
</button>
</div>
<div style={{ display: 'grid', gap: '20px', gridTemplateColumns: '1fr 1fr' }}>
{/* Ternary Version */}
<div style={{ padding: '20px', background: '#ffebee', borderRadius: '8px' }}>
<h3 style={{ color: '#c62828', marginTop: 0 }}>β Ternary (Messy)</h3>
<pre style={{ background: 'white', padding: '10px', borderRadius: '4px', fontSize: '12px' }}>
{`function Component() {
return (
<div>
{condition ? (
<div className="success">
<h1>Welcome!</h1>
<p>All features</p>
<button>Action</button>
</div>
) : (
<div className="error">
<h1>Access Denied</h1>
<p>Please login</p>
</div>
)}
</div>
);
}`}
</pre>
<div style={{ marginTop: '10px', padding: '15px', background: 'white', borderRadius: '4px' }}>
<TernaryVersion isAllowed={condition === 'true'} />
</div>
</div>
{/* Early Return Version */}
<div style={{ padding: '20px', background: '#e8f5e9', borderRadius: '8px' }}>
<h3 style={{ color: '#2e7d32', marginTop: 0 }}>β
Early Return (Clean)</h3>
<pre style={{ background: 'white', padding: '10px', borderRadius: '4px', fontSize: '12px' }}>
{`function Component() {
if (!condition) {
return (
<div className="error">
<h1>Access Denied</h1>
<p>Please login</p>
</div>
);
}
return (
<div className="success">
<h1>Welcome!</h1>
<p>All features</p>
<button>Action</button>
</div>
);
}`}
</pre>
<div style={{ marginTop: '10px', padding: '15px', background: 'white', borderRadius: '4px' }}>
<EarlyReturnVersion isAllowed={condition === 'true'} />
</div>
</div>
</div>
<div style={{ marginTop: '20px', padding: '15px', background: '#fff3e0', borderRadius: '8px' }}>
<strong>π‘ When to Use Early Returns:</strong>
<ul style={{ margin: '10px 0 0 0' }}>
<li>Completely different UI based on condition</li>
<li>Guard clauses (not logged in, no permission, loading)</li>
<li>Complex components with many states</li>
<li>When you want to avoid nested ternaries</li>
</ul>
</div>
</div>
);
}
function TernaryVersion({ isAllowed }) {
return (
<div>
{isAllowed ? (
<div style={{ padding: '15px', background: '#e8f5e9', borderRadius: '8px' }}>
<h4 style={{ color: '#2e7d32', margin: '0 0 10px 0' }}>β Welcome!</h4>
<p style={{ margin: '0 0 10px 0' }}>You have full access</p>
<button style={{ padding: '8px 16px', background: '#4caf50', color: 'white', border: 'none', borderRadius: '4px' }}>
Continue
</button>
</div>
) : (
<div style={{ padding: '15px', background: '#ffebee', borderRadius: '8px' }}>
<h4 style={{ color: '#c62828', margin: '0 0 10px 0' }}>β Access Denied</h4>
<p style={{ margin: 0 }}>Please log in first</p>
</div>
)}
</div>
);
}
function EarlyReturnVersion({ isAllowed }) {
if (!isAllowed) {
return (
<div style={{ padding: '15px', background: '#ffebee', borderRadius: '8px' }}>
<h4 style={{ color: '#c62828', margin: '0 0 10px 0' }}>β Access Denied</h4>
<p style={{ margin: 0 }}>Please log in first</p>
</div>
);
}
return (
<div style={{ padding: '15px', background: '#e8f5e9', borderRadius: '8px' }}>
<h4 style={{ color: '#2e7d32', margin: '0 0 10px 0' }}>β Welcome!</h4>
<p style={{ margin: '0 0 10px 0' }}>You have full access</p>
<button style={{ padding: '8px 16px', background: '#4caf50', color: 'white', border: 'none', borderRadius: '4px' }}>
Continue
</button>
</div>
);
}
export default EarlyReturnsMasterClass;
π§ Memory Aids for Poor Logic Thinking
Early Return Pattern Card
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β EARLY RETURNS - THE PATTERN β
β β
β STRUCTURE: β
β function Component() { β
β // GUARD CLAUSES (Early returns) β
β if (!user) return <Login />; β
β if (loading) return <Spinner />; β
β if (error) return <Error />; β
β if (noData) return <Empty />; β
β β
β // MAIN RETURN (Only if all guards pass) β
β return ( β
β <div> β
β <h1>Welcome!</h1> β
β {/* Full component */} β
β </div> β
β ); β
β } β
β β
β VISUAL: BOUNCER AT CLUB β
β β
β πͺ ENTRANCE β
β β β
β [No ID?] β β GO HOME (Early return) β
β β Yes β
β [Wrong clothes?] β β GO CHANGE β
β β Yes β
β [Too drunk?] β β GO SOBER UP β
β β Yes β
β [All good?] β β
COME IN! (Normal return) β
β β
β KEY RULE: β
β Each early return STOPS the function! β
β Code after early return NEVER runs! β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
When to Use What Comparison
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β CONDITIONAL RENDERING METHODS COMPARISON β
β β
β βββββββββββββββββββ¬ββββββββββββββββββββββββββ β
β β && OPERATOR β Early Return β β
β βββββββββββββββββββΌββββββββββββββββββββββββββ€ β
β β {show && <A />} β if (!ready) return <B />β β
β β β β β
β β β’ Inside JSX β β’ Outside JSX β β
β β β’ Simple show/ β β’ Before return β β
β β hide β β’ Guard clauses β β
β β β’ Optional UI β β’ Different components β β
β βββββββββββββββββββΌββββββββββββββββββββββββββ€ β
β β TERNARY β Early Return β β
β βββββββββββββββββββΌββββββββββββββββββββββββββ€ β
β β {x ? <A /> : β if (x) return <A />; β β
β β <B />} β return <B />; β β
β β β β β
β β β’ Inside JSX β β’ Outside JSX β β
β β β’ Similar UI β β’ Completely different β β
β β structure β UI structure β β
β β β’ Small diff β β’ Large differences β β
β βββββββββββββββββββ΄ββββββββββββββββββββββββββ β
β β
β DECISION TREE: β
β β
β Is the condition a "guard" (block access)? β
β β YES β Early Return β
β β
β Is it optional content in same layout? β
β β YES β && Operator β
β β
β Is it a toggle between two views? β
β β YES β Ternary OR Early Return β
β β
β Are the two views very different? β
β β YES β Early Return (cleaner) β
β β NO β Ternary (simpler) β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Common Early Return Patterns
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β COMMON EARLY RETURN PATTERNS β
β β
β 1. AUTHENTICATION GUARD: β
β if (!user) return <LoginPrompt />; β
β if (!user.isAdmin) return <AccessDenied />; β
β β
β 2. LOADING GUARD: β
β if (isLoading) return <Spinner />; β
β if (!data) return <Loading />; β
β β
β 3. ERROR GUARD: β
β if (error) return <ErrorMessage error={error} />; β
β if (fetchFailed) return <RetryButton />; β
β β
β 4. EMPTY STATE GUARD: β
β if (items.length === 0) return <EmptyState />; β
β if (!hasPermission) return null; β
β β
β 5. MULTI-STEP FORM: β
β if (step === 1) return <Step1 />; β
β if (step === 2) return <Step2 />; β
β if (step === 3) return <Step3 />; β
β β
β 6. FEATURE FLAGS: β
β if (!featureEnabled) return null; β
β if (betaOnly && !isBetaUser) return <Upgrade />; β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Code Structure Visual
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β GOOD vs BAD COMPONENT STRUCTURE β
β β
β β BAD: Nested Ternaries (Confusing) β
β function Component() { β
β return ( β
β <div> β
β {loading ? ( β
β <Spinner /> β
β ) : error ? ( β
β <Error /> β
β ) : !data ? ( β
β <Empty /> β
β ) : ( β
β <Content /> β
β )} β
β </div> β
β ); β
β } β
β β
β β
GOOD: Early Returns (Clean) β
β function Component() { β
β if (loading) return <Spinner />; β
β if (error) return <Error />; β
β if (!data) return <Empty />; β
β β
β return ( β
β <div> β
β <Content /> β
β </div> β
β ); β
β } β
β β
β WHY EARLY RETURNS ARE BETTER: β
β β’ Each condition is separate and clear β
β β’ No nested braces to track β
β β’ Main return is clean and focused β
β β’ Easy to add new guards β
β β’ Reads top to bottom like a checklist β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
π Practice Exercises
Exercise 1: Convert Ternary to Early Return
Convert this messy ternary to clean early returns:
function MessyDashboard({ user, isLoading, error, data }) {
return (
<div className="dashboard">
{isLoading ? (
<p>Loading...</p>
) : error ? (
<p>Error: {error}</p>
) : !user ? (
<p>Please log in</p>
) : !data ? (
<p>No data</p>
) : (
<div>
<h1>Welcome {user.name}</h1>
<DataTable data={data} />
</div>
)}
</div>
);
}
Solution:
function CleanDashboard({ user, isLoading, error, data }) {
// Guard clauses - each stops the function if true
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
if (!user) return <p>Please log in</p>;
if (!data) return <p>No data</p>;
// Main content - only reached if all guards pass
return (
<div className="dashboard">
<h1>Welcome {user.name}</h1>
<DataTable data={data} />
</div>
);
}
Exercise 2: Build a Multi-Step Form
Create a registration form with 3 steps using early returns:
// TODO: Create MultiStepForm with early returns
// Step 1: Account (username, password)
// Step 2: Profile (name, email, bio)
// Step 3: Review & Submit
function MultiStepForm() {
// TODO: State for current step and form data
// TODO: Early returns for each step
return (
<div>
{/* This should never render if early returns work */}
<p>Error: Unknown step</p>
</div>
);
}
Solution:
import { useState } from 'react';
function MultiStepForm({ onSubmit }) {
const [step, setStep] = useState(1);
const [formData, setFormData] = useState({
username: '',
password: '',
name: '',
email: '',
bio: ''
});
const updateField = (field, value) => {
setFormData(prev => ({ ...prev, [field]: value }));
};
// EARLY RETURN: Step 1 - Account
if (step === 1) {
return (
<div style={{ maxWidth: '400px', margin: '0 auto', padding: '20px' }}>
<h2>Step 1: Account</h2>
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
<input
placeholder="Username"
value={formData.username}
onChange={(e) => updateField('username', e.target.value)}
style={{ padding: '10px' }}
/>
<input
type="password"
placeholder="Password"
value={formData.password}
onChange={(e) => updateField('password', e.target.value)}
style={{ padding: '10px' }}
/>
<button
onClick={() => setStep(2)}
disabled={!formData.username || !formData.password}
style={{ padding: '10px', background: '#4caf50', color: 'white', border: 'none' }}
>
Next β
</button>
</div>
</div>
);
}
// EARLY RETURN: Step 2 - Profile
if (step === 2) {
return (
<div style={{ maxWidth: '400px', margin: '0 auto', padding: '20px' }}>
<h2>Step 2: Profile</h2>
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
<input
placeholder="Full Name"
value={formData.name}
onChange={(e) => updateField('name', e.target.value)}
style={{ padding: '10px' }}
/>
<input
type="email"
placeholder="Email"
value={formData.email}
onChange={(e) => updateField('email', e.target.value)}
style={{ padding: '10px' }}
/>
<textarea
placeholder="Bio"
value={formData.bio}
onChange={(e) => updateField('bio', e.target.value)}
style={{ padding: '10px', height: '80px' }}
/>
<div style={{ display: 'flex', gap: '10px' }}>
<button
onClick={() => setStep(1)}
style={{ flex: 1, padding: '10px' }}
>
β Back
</button>
<button
onClick={() => setStep(3)}
disabled={!formData.name || !formData.email}
style={{ flex: 1, padding: '10px', background: '#4caf50', color: 'white', border: 'none' }}
>
Next β
</button>
</div>
</div>
</div>
);
}
// EARLY RETURN: Step 3 - Review
if (step === 3) {
return (
<div style={{ maxWidth: '400px', margin: '0 auto', padding: '20px' }}>
<h2>Step 3: Review</h2>
<div style={{ background: '#f5f5f5', padding: '15px', borderRadius: '8px', marginBottom: '15px' }}>
<p><strong>Username:</strong> {formData.username}</p>
<p><strong>Name:</strong> {formData.name}</p>
<p><strong>Email:</strong> {formData.email}</p>
<p><strong>Bio:</strong> {formData.bio || '(none)'}</p>
</div>
<div style={{ display: 'flex', gap: '10px' }}>
<button
onClick={() => setStep(2)}
style={{ flex: 1, padding: '10px' }}
>
β Back
</button>
<button
onClick={() => onSubmit(formData)}
style={{ flex: 1, padding: '10px', background: '#4caf50', color: 'white', border: 'none' }}
>
Submit β
</button>
</div>
</div>
);
}
// Fallback (should never reach here)
return <p>Unknown step: {step}</p>;
}
Exercise 3: Fix the Broken Early Return
This code has a bug - the early return never triggers. Find and fix it:
function BrokenGuard({ user }) {
// BUG: This condition is wrong!
if (user.isLoggedIn) {
return <p>Please log in</p>;
}
return (
<div>
<h1>Welcome {user.name}</h1>
<p>Your dashboard</p>
</div>
);
}
Solution:
function FixedGuard({ user }) {
// Fixed: Check if NOT logged in (missing !)
if (!user || !user.isLoggedIn) {
return <p>Please log in</p>;
}
return (
<div>
<h1>Welcome {user.name}</h1>
<p>Your dashboard</p>
</div>
);
}
// Common guard patterns:
// if (!user) β No user object exists
// if (!user.isLoggedIn) β User exists but not logged in
// if (user.isLoggedIn === false) β Explicitly false
π‘ Key Takeaways
| Concept | What It Means | Example |
|---|---|---|
| Early Return | Return immediately based on condition | if (!user) return <Login /> |
| Guard Clause | Early return that protects main logic | if (loading) return <Spinner /> |
| vs Ternary | Early return is outside JSX, ternary is inside | Use early return for completely different UI |
| vs && | Early return replaces entire component, && adds optional piece | Use && for optional elements |
| null return | return null renders nothing | if (soldOut) return null |
| Flow Control | Code after early return never runs | Like an exit door |
The Early Return Pattern:
function Component() {
// Guards (stop if conditions met)
if (condition1) return <A />;
if (condition2) return <B />;
// Main content (only if all guards pass)
return <MainContent />;
}
When to Use What:
- Early Return: Completely different UI, guard clauses, loading/error states
- Ternary: Toggle between two similar views inside JSX
- &&: Optional content within same layout
One Sentence Summary: > "Use early returns by writing if (condition) return <Component /> at the top of your component function to immediately exit with different UI based on conditions β this creates clean 'guard clauses' that handle special cases before the main return, making your code more readable than nested ternaries!"