🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples React
Exemples de composants React.js incluant hooks, gestion d'état, routing et patterns React modernes
💻 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. Component with state
import { useState } 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
import { useState, useEffect } from 'react';
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
};