Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Comment React.memo utilise la comparaison superficielle pour ignorer le rendu des composants enfants inchangés.
Par défaut, React re-rend un composant chaque fois que son parent se re-rend — que les props du composant aient changé ou non. React.memo est un composant d'ordre supérieur qui enveloppe un composant fonctionnel et mémoïse sa sortie de rendu. Il effectue une comparaison superficielle des props précédentes et nouvelles, et ignore le re-rendu si elles sont égales.
Lorsque le state d'un composant parent change, React appelle la fonction du parent. Puis il traite tous les enfants JSX retournés — appelant aussi leurs fonctions, même si leurs props sont identiques. Cela se propage vers le bas de l'arbre.
React.memo(Component) retourne un nouveau composant. Avant d'appeler la fonction de Component, React vérifie si les nouvelles props sont superficiellement égales aux props précédentes. Si oui, React réutilise la sortie de rendu précédente — ignorant entièrement l'appel de la fonction.
Pour chaque clé de prop, React compare ancienneProp === nouvelleProp. Les primitives (string, number, boolean) se comparent par valeur. Les objets et fonctions se comparent par référence — un nouvel objet littéral '{''}' dans les props échoue toujours au contrôle d'égalité.
React.memo(Component, sontPropsÉgales) accepte un second argument — une fonction de comparaison personnalisée. Retournez true pour ignorer le re-rendu (props égales), false pour l'autoriser. Utile pour les vérifications d'égalité profonde ou pour ignorer des props spécifiques.
React.memo ignore seulement les re-rendus causés par des changements de props. Si le composant appelle useContext(), il se re-rendra quand même lorsque la valeur du contexte change — indépendamment de React.memo.
HOC qui mémoïse la sortie de rendu d'un composant. Ignore le re-rendu lorsque les props sont superficiellement égales au rendu précédent.
Compare chaque prop avec Object.is(). Efficace pour les primitives. Les objets et fonctions doivent maintenir la même référence entre les rendus.
Lorsque React.memo détermine que les props sont égales, il retourne la sortie de rendu précédente et ignore l'appel de la fonction composant.
Conserver la même référence d'objet/fonction entre les rendus. Nécessaire pour que React.memo fonctionne correctement avec des props non primitives.
Un re-rendu où la sortie est identique au rendu précédent. React.memo les prévient lorsque les props n'ont pas changé logiquement.
1// Without memo — re-renders every time parent renders2function ExpensiveList({ items }) {3 return items.map(item => <Item key={item.id} {...item} />);4}56// With memo — skips re-render if items reference is stable7const ExpensiveList = React.memo(function ExpensiveList({ items }) {8 return items.map(item => <Item key={item.id} {...item} />);9});1011function Parent() {12 const [count, setCount] = useState(0);1314 // ❌ New array every render — memo never helps15 const items = [{ id: 1, name: 'Apple' }];1617 // ✅ Stable reference — memo works as expected18 const items = useMemo(() => [{ id: 1, name: 'Apple' }], []);1920 return (21 <>22 <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>23 <ExpensiveList items={items} /> {/* skips re-render when only count changes */}24 </>25 );26}
Dans les grands arbres React avec des composants complexes, les re-rendus inutiles s'accumulent en de vrais problèmes de performance — interactions lentes, frames perdues, animations saccadées. React.memo vous permet de prévenir chirurgicalement le re-rendu de composants spécifiques, gardant les sous-arbres coûteux stables pendant que le reste de l'application se met à jour librement.
A Slack-like app renders a message list. When a user types in the input box, the entire list of 1000+ message components re-renders because the parent (ChatRoom) updates on every keystroke.
Each keystroke updates the parent's `inputValue` state, triggering a re-render. Without React.memo, all 1000 Message components re-render even though none of their props changed. Each Message component does string formatting and date calculations — the combined cost creates visible lag.
Wrap Message in React.memo: `const Message = React.memo(({ text, author, timestamp }) => { ... })`. Since the message props are primitive values (strings, numbers), React.memo's shallow comparison correctly identifies that nothing changed. The 1000 messages are skipped entirely — only the input re-renders.
Takeaway: React.memo shines when a parent re-renders frequently but a child's props rarely change. The ideal candidates are list items, complex charts, and any component with expensive rendering where the parent updates for unrelated reasons.
A MapWidget receives a `coordinates` object `{ lat: 40.7, lng: -74.0 }`. Despite wrapping in React.memo, it still re-renders because the parent creates a new coordinates object each render.
React.memo uses shallow comparison by default: `oldCoords !== newCoords` is always true because each render creates a new object, even if lat/lng values are identical. Shallow comparison checks reference equality, not value equality.
Provide a custom comparison: `React.memo(MapWidget, (prev, next) => prev.coordinates.lat === next.coordinates.lat && prev.coordinates.lng === next.coordinates.lng)`. Now React.memo compares the actual values instead of the object reference. Alternatively, flatten the props: `<MapWidget lat={40.7} lng={-74.0} />` — primitives compare by value automatically.
Takeaway: Use custom areEqual functions for components that receive objects or arrays as props and can't be easily memoized upstream. But first, consider if you can flatten the props to primitives or memoize the object with useMemo in the parent — these are simpler and more maintainable.