// Composants fonctionnels
function UserProfile({ user }) {
return (
<div className="profile">
<h2>{user.name}</h2>
<UserAvatar user={user} />
<UserInfo user={user} />
</div>
);
}
// Props avec valeurs par défaut
function Button({ type = 'button', children }) {
return (
<button type={type}>
{children}
</button>
);
}
// Destructuration des props
function UserCard({ name, email, avatar }) {
return (
<div>
<img src={avatar} alt={name} />
<h3>{name}</h3>
<p>{email}</p>
</div>
);
}
// Ne pas modifier les props
function BadComponent(props) {
props.value = 123; // ❌ Mauvais!
}
// Éviter les composants trop complexes
function HugeComponent() {
// ❌ Trop de logique et d'état
const [state1, setState1] = useState();
const [state2, setState2] = useState();
const [state3, setState3] = useState();
// ...plus de 100 lignes de code
}
// État local simple
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
{count}
</button>
);
}
// État complexe avec reducer
function TodoList() {
const [todos, dispatch] = useReducer(todoReducer, []);
// Actions bien définies
const addTodo = useCallback((text) => {
dispatch({ type: 'ADD_TODO', payload: text });
}, []);
}
// Ne pas mettre à jour l'état directement
const [items, setItems] = useState([]);
items.push(newItem); // ❌ Mauvais!
// Éviter les mises à jour synchrones multiples
setCount(count + 1);
setCount(count + 1); // ❌ Ne fonctionne pas
// Mémoisation des composants
const MemoizedComponent = React.memo(
function ExpensiveComponent({ data }) {
return <div>{/* Rendu coûteux */}</div>
}
);
// Mémoisation des calculs
function DataList({ items }) {
const sortedItems = useMemo(
() => items.sort((a, b) => b - a),
[items]
);
const handleClick = useCallback(
() => {
// Action
},
[]
);
}
// Code splitting
const LazyComponent = React.lazy(
() => import('./LazyComponent')
);
function App() {
return (
<Suspense fallback={<Loader />}>
<LazyComponent />
</Suspense>
);
}
// Pagination et chargement virtualisé
import { VirtualScroller } from 'react-virtual';
src/
├── components/ # Composants réutilisables
│ ├── Button/
│ │ ├── index.js
│ │ ├── Button.js
│ │ └── Button.css
│ └── Card/
├── pages/ # Pages/Routes
├── hooks/ # Hooks personnalisés
├── context/ # Contextes React
├── utils/ # Fonctions utilitaires
├── services/ # Appels API
└── assets/ # Images, fonts, etc.
// Test de composant
import { render, fireEvent } from '@testing-library/react';
test('bouton incrémente le compteur', () => {
const { getByText } = render(<Counter />);
const button = getByText('0');
fireEvent.click(button);
expect(button).toHaveTextContent('1');
});
// Test de hook personnalisé
import { renderHook, act } from '@testing-library/react-hooks';