function TodoApp() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
const addTodo = (e) => {
e.preventDefault();
if (!input.trim()) return;
setTodos([
...todos,
{
id: Date.now(),
text: input,
completed: false
}
]);
setInput('');
};
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id
? { ...todo, completed: !todo.completed }
: todo
));
};
return (
<div className="todo-app">
<form onSubmit={addTodo}>
<input
value={input}
onChange={e => setInput(e.target.value)}
placeholder="Ajouter une tâche"
/>
<button type="submit">Ajouter</button>
</form>
<ul>
{todos.map(todo => (
<li
key={todo.id}
style={{
textDecoration: todo.completed
? 'line-through'
: 'none'
}}
onClick={() => toggleTodo(todo.id)}
>
{todo.text}
</li>
))}
</ul>
</div>
);
}
// Composant Modal
function Modal({ isOpen, onClose, title, children }) {
if (!isOpen) return null;
return (
<div className="modal-overlay">
<div className="modal-content">
<div className="modal-header">
<h2>{title}</h2>
<button onClick={onClose}>×</button>
</div>
<div className="modal-body">
{children}
</div>
</div>
</div>
);
}
// Utilisation
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>
Ouvrir Modal
</button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Mon Modal"
>
<p>Contenu du modal...</p>
</Modal>
</div>
);
}
function RegisterForm() {
const [formData, setFormData] = useState({
username: '',
email: '',
password: ''
});
const [errors, setErrors] = useState({});
const validate = () => {
const newErrors = {};
if (!formData.username) {
newErrors.username = 'Nom requis';
}
if (!formData.email.includes('@')) {
newErrors.email = 'Email invalide';
}
if (formData.password.length < 6) {
newErrors.password =
'Mot de passe trop court';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e) => {
e.preventDefault();
if (validate()) {
// Soumettre le formulaire
console.log('Form valid:', formData);
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<input
name="username"
value={formData.username}
onChange={e => setFormData({
...formData,
username: e.target.value
})}
/>
{errors.username && (
<span className="error">
{errors.username}
</span>
)}
</div>
{/* Autres champs... */}
</form>
);
}
function InfiniteList() {
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
const loader = useRef(null);
const loadMore = useCallback(async () => {
if (loading) return;
setLoading(true);
try {
const response = await fetch(
`/api/items?page=${page}`
);
const newItems = await response.json();
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
} catch (error) {
console.error('Error:', error);
} finally {
setLoading(false);
}
}, [page, loading]);
useEffect(() => {
const observer = new IntersectionObserver(
entries => {
if (entries[0].isIntersecting) {
loadMore();
}
}
);
if (loader.current) {
observer.observe(loader.current);
}
return () => observer.disconnect();
}, [loadMore]);
return (
<div>
{items.map(item => (
<div key={item.id}>
{item.title}
</div>
))}
{loading && <div>Chargement...</div>}
<div ref={loader} />
</div>
);
}