Exemples React

Exemples de composants React.js incluant hooks, gestion d'état, routing et patterns React modernes

Key Facts

Category
Web Frameworks
Items
3
Format Families
text

Sample Overview

Exemples de composants React.js incluant hooks, gestion d'état, routing et patterns React modernes This sample set belongs to Web Frameworks and can be used to test related workflows inside Elysia Tools.

💻 React Hello World javascript

🟢 simple

Exemples de composants React de base et application Hello World avec JSX

⏱️ 15 min 🏷️ react, jsx, components, hooks
Prerequisites: JavaScript basics, HTML basics
// React Hello World Examples

// 1. Basic functional component
function HelloWorld() {
    return <h1>Hello, World!</h1>;
}

// 2. Component with props
function Greeting({ name }) {
    return <h1>Hello, {name}!</h1>;
}

// 3. Components with hooks
import { useState, useEffect } from 'react';

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <h1>Count: {count}</h1>
            <button onClick={() => setCount(count + 1)}>
                Increment
            </button>
            <button onClick={() => setCount(count - 1)}>
                Decrement
            </button>
        </div>
    );
}

// 4. Component with multiple states
function UserForm() {
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');

    const handleSubmit = (e) => {
        e.preventDefault();
        alert(`Name: ${name}, Email: ${email}`);
    };

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label>Name: </label>
                <input
                    type="text"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                />
            </div>
            <div>
                <label>Email: </label>
                <input
                    type="email"
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                />
            </div>
            <button type="submit">Submit</button>
        </form>
    );
}

// 5. Conditional rendering
function WelcomeMessage({ isLoggedIn }) {
    return (
        <div>
            {isLoggedIn ? (
                <h1>Welcome back!</h1>
            ) : (
                <h1>Please sign in</h1>
            )}
        </div>
    );
}

// 6. List rendering
function TodoList() {
    const todos = [
        { id: 1, text: 'Learn React', completed: false },
        { id: 2, text: 'Build a project', completed: false },
        { id: 3, text: 'Deploy to production', completed: true }
    ];

    return (
        <ul>
            {todos.map(todo => (
                <li key={todo.id} style={{
                    textDecoration: todo.completed ? 'line-through' : 'none'
                }}>
                    {todo.text}
                </li>
            ))}
        </ul>
    );
}

// 7. Event handling
function ButtonExample() {
    const handleClick = () => {
        alert('Button clicked!');
    };

    const handleMouseOver = () => {
        console.log('Mouse over button');
    };

    return (
        <div>
            <button onClick={handleClick}>
                Click me
            </button>
            <button onMouseOver={handleMouseOver}>
                Hover over me
            </button>
        </div>
    );
}

// 8. Component with useEffect

function Timer() {
    const [seconds, setSeconds] = useState(0);

    useEffect(() => {
        const interval = setInterval(() => {
            setSeconds(seconds => seconds + 1);
        }, 1000);

        return () => clearInterval(interval);
    }, []);

    return (
        <div>
            <h1>Timer: {seconds}s</h1>
        </div>
    );
}

// 9. Fetching data with useEffect
function UserProfile({ userId }) {
    const [user, setUser] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
            .then(response => response.json())
            .then(data => {
                setUser(data);
                setLoading(false);
            })
            .catch(error => {
                console.error('Error fetching user:', error);
                setLoading(false);
            });
    }, [userId]);

    if (loading) return <div>Loading...</div>;
    if (!user) return <div>User not found</div>;

    return (
        <div>
            <h2>{user.name}</h2>
            <p>Email: {user.email}</p>
            <p>Phone: {user.phone}</p>
            <p>Website: {user.website}</p>
        </div>
    );
}

// 10. Custom hook example
function useCounter(initialValue = 0) {
    const [count, setCount] = useState(initialValue);

    const increment = () => setCount(count + 1);
    const decrement = () => setCount(count - 1);
    const reset = () => setCount(initialValue);

    return { count, increment, decrement, reset };
}

function CustomCounter() {
    const { count, increment, decrement, reset } = useCounter(10);

    return (
        <div>
            <h1>Count: {count}</h1>
            <button onClick={increment}>+</button>
            <button onClick={decrement}>-</button>
            <button onClick={reset}>Reset</button>
        </div>
    );
}

// 11. Component composition
function Card({ title, children }) {
    return (
        <div style={{
            border: '1px solid #ccc',
            borderRadius: '8px',
            padding: '16px',
            margin: '16px'
        }}>
            <h3>{title}</h3>
            {children}
        </div>
    );
}

function App() {
    return (
        <div>
            <Card title="Welcome">
                <p>This is a card component with children.</p>
                <HelloWorld />
            </Card>
            <Card title="Counter">
                <Counter />
            </Card>
            <Card title="Timer">
                <Timer />
            </Card>
        </div>
    );
}

export {
    HelloWorld,
    Greeting,
    Counter,
    UserForm,
    WelcomeMessage,
    TodoList,
    ButtonExample,
    Timer,
    UserProfile,
    CustomCounter,
    Card,
    App
};

💻 Hooks Avancés React javascript

🟡 intermediate ⭐⭐⭐⭐

Exemples complexes de hooks React incluant useContext, useReducer, useMemo et useCallback

⏱️ 35 min 🏷️ react, hooks, state, performance
Prerequisites: React basics, JavaScript ES6+, State management concepts
// Advanced React Hooks Examples

import { useState, useContext, createContext, useReducer, useMemo, useCallback, useRef, useEffect } from 'react';

// 1. useContext Example
const ThemeContext = createContext();

function ThemeProvider({ children }) {
    const [theme, setTheme] = useState('light');

    const toggleTheme = () => {
        setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
    };

    return (
        <ThemeContext.Provider value={{ theme, toggleTheme }}>
            {children}
        </ThemeContext.Provider>
    );
}

function ThemedComponent() {
    const { theme, toggleTheme } = useContext(ThemeContext);

    const styles = {
        backgroundColor: theme === 'light' ? '#fff' : '#333',
        color: theme === 'light' ? '#333' : '#fff',
        padding: '20px',
        borderRadius: '8px'
    };

    return (
        <div style={styles}>
            <h2>Current Theme: {theme}</h2>
            <button onClick={toggleTheme}>Toggle Theme</button>
        </div>
    );
}

// 2. useReducer Example
const initialState = {
    count: 0,
    history: []
};

function counterReducer(state, action) {
    switch (action.type) {
        case 'increment':
            return {
                count: state.count + 1,
                history: [...state.history, `Increment to ${state.count + 1}`]
            };
        case 'decrement':
            return {
                count: state.count - 1,
                history: [...state.history, `Decrement to ${state.count - 1}`]
            };
        case 'reset':
            return {
                count: 0,
                history: []
            };
        default:
            return state;
    }
}

function CounterWithReducer() {
    const [state, dispatch] = useReducer(counterReducer, initialState);

    return (
        <div>
            <h1>Count: {state.count}</h1>
            <button onClick={() => dispatch({ type: 'increment' })}>
                +
            </button>
            <button onClick={() => dispatch({ type: 'decrement' })}>
                -
            </button>
            <button onClick={() => dispatch({ type: 'reset' })}>
                Reset
            </button>
            <h3>History:</h3>
            <ul>
                {state.history.map((item, index) => (
                    <li key={index}>{item}</li>
                ))}
            </ul>
        </div>
    );
}

// 3. useMemo Example
function ExpensiveComponent({ number }) {
    const expensiveCalculation = useMemo(() => {
        console.log('Running expensive calculation...');
        let result = 0;
        for (let i = 0; i < number * 1000000; i++) {
            result += Math.sqrt(i);
        }
        return Math.round(result);
    }, [number]);

    return (
        <div>
            <h3>Expensive Calculation Result: {expensiveCalculation}</h3>
            <p>Input number: {number}</p>
        </div>
    );
}

// 4. useCallback Example
function ParentComponent() {
    const [count, setCount] = useState(0);

    const handleClick = useCallback(() => {
        console.log('Button clicked! Count:', count);
    }, [count]);

    return (
        <div>
            <h1>Count: {count}</h1>
            <button onClick={() => setCount(count + 1)}>
                Increment
            </button>
            <ChildButton onClick={handleClick} />
        </div>
    );
}

// Memoized child component
const ChildButton = React.memo(({ onClick }) => {
    console.log('ChildButton rendered');
    return <button onClick={onClick}>Child Button</button>;
});

// 5. useRef Example
function RefExample() {
    const inputRef = useRef(null);
    const countRef = useRef(0);

    const focusInput = () => {
        inputRef.current.focus();
    };

    const incrementRef = () => {
        countRef.current += 1;
        console.log('Ref count:', countRef.current);
    };

    return (
        <div>
            <input ref={inputRef} type="text" placeholder="Focus me" />
            <button onClick={focusInput}>Focus Input</button>
            <button onClick={incrementRef}>Increment Ref</button>
        </div>
    );
}

// 6. Custom Hook: useLocalStorage
function useLocalStorage(key, initialValue) {
    const [storedValue, setStoredValue] = useState(() => {
        try {
            const item = window.localStorage.getItem(key);
            return item ? JSON.parse(item) : initialValue;
        } catch (error) {
            console.error('Error reading localStorage:', error);
            return initialValue;
        }
    });

    const setValue = useCallback((value) => {
        try {
            const valueToStore = value instanceof Function ? value(storedValue) : value;
            setStoredValue(valueToStore);
            window.localStorage.setItem(key, JSON.stringify(valueToStore));
        } catch (error) {
            console.error('Error setting localStorage:', error);
        }
    }, [key, storedValue]);

    return [storedValue, setValue];
}

function LocalStorageExample() {
    const [name, setName] = useLocalStorage('userName', '');

    return (
        <div>
            <input
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="Enter your name"
            />
            <p>Your name: {name}</p>
            <p>(Persisted in localStorage)</p>
        </div>
    );
}

// 7. Custom Hook: useDebounce
function useDebounce(value, delay) {
    const [debouncedValue, setDebouncedValue] = useState(value);

    useEffect(() => {
        const handler = setTimeout(() => {
            setDebouncedValue(value);
        }, delay);

        return () => {
            clearTimeout(handler);
        };
    }, [value, delay]);

    return debouncedValue;
}

function SearchExample() {
    const [searchTerm, setSearchTerm] = useState('');
    const debouncedSearchTerm = useDebounce(searchTerm, 500);

    useEffect(() => {
        if (debouncedSearchTerm) {
            console.log('Searching for:', debouncedSearchTerm);
            // In real app, this would trigger an API call
        }
    }, [debouncedSearchTerm]);

    return (
        <div>
            <input
                type="text"
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                placeholder="Search..."
            />
            <p>Debounced search term: {debouncedSearchTerm}</p>
        </div>
    );
}

// 8. useLayoutEffect Example
function LayoutEffectExample() {
    const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
    const divRef = useRef(null);

    useLayoutEffect(() => {
        if (divRef.current) {
            const { clientWidth, clientHeight } = divRef.current;
            setDimensions({ width: clientWidth, height: clientHeight });
        }
    }, []);

    return (
        <div>
            <div
                ref={divRef}
                style={{
                    width: '300px',
                    height: '200px',
                    backgroundColor: 'lightblue',
                    padding: '20px'
                }}
            >
                <h3>Component with Layout Effect</h3>
                <p>Width: {dimensions.width}px</p>
                <p>Height: {dimensions.height}px</p>
            </div>
        </div>
    );
}

// 9. useImperativeHandle Example (with forwardRef)
const CustomInput = React.forwardRef((props, ref) => {
    const inputRef = useRef(null);

    useImperativeHandle(ref, () => ({
        focus: () => {
            inputRef.current.focus();
        },
        clear: () => {
            inputRef.current.value = '';
        },
        getValue: () => {
            return inputRef.current.value;
        }
    }));

    return <input ref={inputRef} type="text" {...props} />;
});

function ImperativeHandleExample() {
    const inputRef = useRef(null);

    const handleFocus = () => {
        inputRef.current.focus();
    };

    const handleClear = () => {
        inputRef.current.clear();
    };

    const handleGetValue = () => {
        alert(`Input value: ${inputRef.current.getValue()}`);
    };

    return (
        <div>
            <CustomInput ref={inputRef} placeholder="Type something..." />
            <button onClick={handleFocus}>Focus</button>
            <button onClick={handleClear}>Clear</button>
            <button onClick={handleGetValue}>Get Value</button>
        </div>
    );
}

// 10. Combination Example: Todo App with multiple hooks
const initialState = {
    todos: [],
    filter: 'all'
};

function todosReducer(state, action) {
    switch (action.type) {
        case 'add':
            return {
                ...state,
                todos: [...state.todos, {
                    id: Date.now(),
                    text: action.text,
                    completed: false
                }]
            };
        case 'toggle':
            return {
                ...state,
                todos: state.todos.map(todo =>
                    todo.id === action.id
                        ? { ...todo, completed: !todo.completed }
                        : todo
                )
            };
        case 'delete':
            return {
                ...state,
                todos: state.todos.filter(todo => todo.id !== action.id)
            };
        case 'setFilter':
            return { ...state, filter: action.filter };
        default:
            return state;
    }
}

function TodoApp() {
    const [state, dispatch] = useReducer(todosReducer, initialState);
    const [inputText, setInputText] = useState('');

    const filteredTodos = useMemo(() => {
        switch (state.filter) {
            case 'completed':
                return state.todos.filter(todo => todo.completed);
            case 'active':
                return state.todos.filter(todo => !todo.completed);
            default:
                return state.todos;
        }
    }, [state.todos, state.filter]);

    const addTodo = useCallback((text) => {
        if (text.trim()) {
            dispatch({ type: 'add', text: text.trim() });
            setInputText('');
        }
    }, []);

    const handleSubmit = (e) => {
        e.preventDefault();
        addTodo(inputText);
    };

    return (
        <div>
            <h1>Todo App</h1>
            <form onSubmit={handleSubmit}>
                <input
                    value={inputText}
                    onChange={(e) => setInputText(e.target.value)}
                    placeholder="Add new todo..."
                />
                <button type="submit">Add</button>
            </form>

            <div>
                <button onClick={() => dispatch({ type: 'setFilter', filter: 'all' })}>
                    All
                </button>
                <button onClick={() => dispatch({ type: 'setFilter', filter: 'active' })}>
                    Active
                </button>
                <button onClick={() => dispatch({ type: 'setFilter', filter: 'completed' })}>
                    Completed
                </button>
            </div>

            <ul>
                {filteredTodos.map(todo => (
                    <li key={todo.id}>
                        <input
                            type="checkbox"
                            checked={todo.completed}
                            onChange={() => dispatch({ type: 'toggle', id: todo.id })}
                        />
                        <span style={{
                            textDecoration: todo.completed ? 'line-through' : 'none'
                        }}>
                            {todo.text}
                        </span>
                        <button onClick={() => dispatch({ type: 'delete', id: todo.id })}>
                            Delete
                        </button>
                    </li>
                ))}
            </ul>
        </div>
    );
}

export {
    ThemeProvider,
    ThemedComponent,
    CounterWithReducer,
    ExpensiveComponent,
    ParentComponent,
    RefExample,
    LocalStorageExample,
    SearchExample,
    LayoutEffectExample,
    ImperativeHandleExample,
    TodoApp
};

💻 Patterns de Conception React javascript

🔴 complex ⭐⭐⭐⭐⭐

Patterns React communs incluant Composants d'Ordre Supérieure, Render Props et Composants Composés

⏱️ 45 min 🏷️ react, patterns, architecture, advanced
Prerequisites: Advanced React, JavaScript ES6+, Component patterns
// React Design Patterns

import { useState, createContext, useContext } from 'react';

// 1. Higher-Order Component (HOC) Pattern
function withLogging(WrappedComponent) {
    return function WithLoggingComponent(props) {
        console.log(`Rendering ${WrappedComponent.name}`, props);

        return <WrappedComponent {...props} />;
    };
}

function SimpleComponent({ name }) {
    return <h1>Hello, {name}!</h1>;
}

const LoggedComponent = withLogging(SimpleComponent);

// 2. HOC with additional functionality
function withCounter(WrappedComponent) {
    return function WithCounterComponent(props) {
        const [count, setCount] = useState(0);

        return (
            <WrappedComponent
                {...props}
                count={count}
                increment={() => setCount(count + 1)}
                decrement={() => setCount(count - 1)}
            />
        );
    };
}

function CounterDisplay({ count, increment, decrement }) {
    return (
        <div>
            <h2>Count: {count}</h2>
            <button onClick={increment}>+</button>
            <button onClick={decrement}>-</button>
        </div>
    );
}

const EnhancedCounter = withCounter(CounterDisplay);

// 3. Render Props Pattern
class MouseTracker extends React.Component {
    state = { x: 0, y: 0 };

    handleMouseMove = (event) => {
        this.setState({
            x: event.clientX,
            y: event.clientY
        });
    };

    render() {
        return (
            <div style={{ height: '200px', border: '1px solid #ccc' }} onMouseMove={this.handleMouseMove}>
                {this.props.render(this.state)}
            </div>
        );
    }
}

function MouseDisplay() {
    return (
        <MouseTracker
            render={({ x, y }) => (
                <div>
                    <h3>Mouse Position:</h3>
                    <p>X: {x}, Y: {y}</p>
                </div>
            )}
        />
    );
}

// 4. Render Props with children
function MouseTrackerChildren({ children }) {
    const [position, setPosition] = useState({ x: 0, y: 0 });

    const handleMouseMove = (e) => {
        setPosition({ x: e.clientX, y: e.clientY });
    };

    return (
        <div style={{ height: '200px', border: '1px solid #ccc' }} onMouseMove={handleMouseMove}>
            {children(position)}
        </div>
    );
}

function MouseDisplayChildren() {
    return (
        <MouseTrackerChildren>
            {({ x, y }) => (
                <div>
                    <h3>Mouse Position (Children):</h3>
                    <p>X: {x}, Y: {y}</p>
                </div>
            )}
        </MouseTrackerChildren>
    );
}

// 5. Compound Components Pattern
const TabsContext = createContext();

function Tabs({ children, defaultTab = 0 }) {
    const [activeTab, setActiveTab] = useState(defaultTab);

    return (
        <TabsContext.Provider value={{ activeTab, setActiveTab }}>
            <div className="tabs">{children}</div>
        </TabsContext.Provider>
    );
}

function TabList({ children }) {
    return <div className="tab-list">{children}</div>;
}

function Tab({ children, index }) {
    const { activeTab, setActiveTab } = useContext(TabsContext);

    return (
        <button
            className={`tab ${activeTab === index ? 'active' : ''}`}
            onClick={() => setActiveTab(index)}
        >
            {children}
        </button>
    );
}

function TabPanels({ children }) {
    return <div className="tab-panels">{children}</div>;
}

function TabPanel({ children, index }) {
    const { activeTab } = useContext(TabsContext);

    return activeTab === index ? <div className="tab-panel">{children}</div> : null;
}

// Usage of Compound Components
function CompoundComponentExample() {
    return (
        <Tabs defaultTab={0}>
            <TabList>
                <Tab index={0}>Tab 1</Tab>
                <Tab index={1}>Tab 2</Tab>
                <Tab index={2}>Tab 3</Tab>
            </TabList>
            <TabPanels>
                <TabPanel index={0}>Content for Tab 1</TabPanel>
                <TabPanel index={1}>Content for Tab 2</TabPanel>
                <TabPanel index={2}>Content for Tab 3</TabPanel>
            </TabPanels>
        </Tabs>
    );
}

// 6. Provider Pattern
const UserContext = createContext();

function UserProvider({ children }) {
    const [user, setUser] = useState(null);

    const login = (userData) => {
        setUser(userData);
    };

    const logout = () => {
        setUser(null);
    };

    return (
        <UserContext.Provider value={{ user, login, logout }}>
            {children}
        </UserContext.Provider>
    );
}

function useUser() {
    const context = useContext(UserContext);
    if (!context) {
        throw new Error('useUser must be used within a UserProvider');
    }
    return context;
}

function UserProfile() {
    const { user, logout } = useUser();

    if (!user) {
        return <div>Please log in</div>;
    }

    return (
        <div>
            <h2>Welcome, {user.name}!</h2>
            <p>Email: {user.email}</p>
            <button onClick={logout}>Logout</button>
        </div>
    );
}

// 7. State Reducer Pattern
function useToggle(initialState = false) {
    return useReducer((state, action) => {
        switch (action.type) {
            case 'toggle':
                return !state;
            case 'on':
                return true;
            case 'off':
                return false;
            default:
                throw new Error(`Unhandled action type: ${action.type}`);
        }
    }, initialState);
}

function ToggleButton({ onToggle }) {
    const [isOn, toggle] = useToggle();

    const handleClick = () => {
        toggle({ type: 'toggle' });
        onToggle && onToggle(isOn);
    };

    return (
        <button onClick={handleClick}>
            {isOn ? 'ON' : 'OFF'}
        </button>
    );
}

// 8. Control Props Pattern
function Toggle({ on, onChange, children }) {
    const [internalOn, setInternalOn] = useState(false);
    const isOn = on !== undefined ? on : internalOn;

    const handleClick = () => {
        const newOn = !isOn;
        if (onChange) {
            onChange(newOn);
        } else {
            setInternalOn(newOn);
        }
    };

    return (
        <button onClick={handleClick}>
            {children(isOn)}
        </button>
    );
}

function ControlPropsExample() {
    const [isOn, setIsOn] = useState(false);

    return (
        <div>
            <h3>Controlled Toggle:</h3>
            <Toggle on={isOn} onChange={setIsOn}>
                {(isOn) => (isOn ? 'Turn Off' : 'Turn On')}
            </Toggle>
            <p>State: {isOn ? 'ON' : 'OFF'}</p>

            <h3>Uncontrolled Toggle:</h3>
            <Toggle>
                {(isOn) => (isOn ? 'Switch Off' : 'Switch On')}
            </Toggle>
        </div>
    );
}

// 9. Custom Hook Pattern
function useAsync(asyncFn, dependencies = []) {
    const [state, setState] = useState({
        data: null,
        loading: false,
        error: null
    });

    useEffect(() => {
        let isCancelled = false;

        const runAsync = async () => {
            setState(prev => ({ ...prev, loading: true, error: null }));

            try {
                const result = await asyncFn();
                if (!isCancelled) {
                    setState({ data: result, loading: false, error: null });
                }
            } catch (error) {
                if (!isCancelled) {
                    setState({ data: null, loading: false, error });
                }
            }
        };

        runAsync();

        return () => {
            isCancelled = true;
        };
    }, dependencies);

    return state;
}

function AsyncComponent() {
    const { data, loading, error } = useAsync(async () => {
        const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
        return response.json();
    }, []);

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;
    if (!data) return <div>No data</div>;

    return (
        <div>
            <h2>User Data:</h2>
            <p>Name: {data.name}</p>
            <p>Email: {data.email}</p>
            <p>Phone: {data.phone}</p>
        </div>
    );
}

// 10. Presentational vs Container Pattern
// Presentational Component
const UserListPresentational = ({ users, onUserSelect }) => (
    <ul>
        {users.map(user => (
            <li key={user.id} onClick={() => onUserSelect(user.id)}>
                {user.name}
            </li>
        ))}
    </ul>
);

// Container Component
function UserListContainer() {
    const [users, setUsers] = useState([]);
    const [selectedUser, setSelectedUser] = useState(null);

    useEffect(() => {
        fetch('https://jsonplaceholder.typicode.com/users')
            .then(response => response.json())
            .then(data => setUsers(data));
    }, []);

    const handleUserSelect = (userId) => {
        setSelectedUser(userId);
    };

    return (
        <div>
            <UserListPresentational
                users={users}
                onUserSelect={handleUserSelect}
            />
            {selectedUser && <p>Selected user ID: {selectedUser}</p>}
        </div>
    );
}

// Main App Component showing all patterns
function DesignPatternsApp() {
    const [user, login] = useState({ name: 'John Doe', email: '[email protected]' });

    return (
        <div>
            <h1>React Design Patterns</h1>

            <section>
                <h2>HOC Pattern</h2>
                <LoggedComponent name="World" />
                <EnhancedCounter />
            </section>

            <section>
                <h2>Render Props Pattern</h2>
                <MouseDisplay />
                <MouseDisplayChildren />
            </section>

            <section>
                <h2>Compound Components</h2>
                <CompoundComponentExample />
            </section>

            <section>
                <h2>Provider Pattern</h2>
                <UserProvider>
                    <UserProfile />
                </UserProvider>
            </section>

            <section>
                <h2>Control Props Pattern</h2>
                <ControlPropsExample />
            </section>

            <section>
                <h2>Custom Hook Pattern</h2>
                <AsyncComponent />
            </section>

            <section>
                <h2>Container/Presentational Pattern</h2>
                <UserListContainer />
            </section>
        </div>
    );
}

export {
    withLogging,
    withCounter,
    LoggedComponent,
    EnhancedCounter,
    MouseTracker,
    MouseDisplay,
    Tabs,
    TabList,
    Tab,
    TabPanels,
    TabPanel,
    UserProvider,
    useUser,
    UserProfile,
    useToggle,
    ToggleButton,
    Toggle,
    ControlPropsExample,
    useAsync,
    AsyncComponent,
    UserListPresentational,
    UserListContainer,
    DesignPatternsApp
};