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.
Wie React.memo flachen Vergleich nutzt, um das Rendering unveränderter Kindkomponenten zu überspringen.
Standardmäßig rendert React eine Komponente immer dann neu, wenn ihr Elternteil neu rendert — unabhängig davon, ob sich die eigenen Props der Komponente geändert haben. React.memo ist eine Higher-Order-Komponente, die eine Funktionskomponente umhüllt und ihre Render-Ausgabe memoisiert. Es führt einen flachen Vergleich der vorherigen und neuen Props durch und überspringt das Re-Rendering, wenn sie gleich sind.
Wenn sich der Zustand einer Elternkomponente ändert, ruft React die Funktion der Elternkomponente auf. Dann verarbeitet es alle zurückgegebenen JSX-Kinder — ruft auch ihre Funktionen auf, selbst wenn ihre Props identisch sind. Dies kaskadiert den Baum hinunter.
React.memo(Komponente) gibt eine neue Komponente zurück. Bevor die Funktion der Komponente aufgerufen wird, prüft React, ob die neuen Props flach gleich den vorherigen Props sind. Falls ja, verwendet React die vorherige Render-Ausgabe erneut — der Funktionsaufruf wird vollständig übersprungen.
Für jeden Prop-Schlüssel vergleicht React alteProp === neueProp. Primitive Werte (String, Zahl, Boolean) werden nach Wert verglichen. Objekte und Funktionen werden nach Referenz verglichen — ein neues Objektliteral '{''}' in Props scheitert immer an der Gleichheitsprüfung.
React.memo(Komponente, sindPropsGleich) akzeptiert ein zweites Argument — eine benutzerdefinierte Vergleichsfunktion. Geben Sie true zurück, um das Re-Rendering zu überspringen (Props sind gleich), false, um es zuzulassen. Nützlich für tiefe Gleichheitsprüfungen oder das Ignorieren bestimmter Props.
React.memo überspringt nur Re-Renderings, die durch Prop-Änderungen verursacht werden. Wenn die Komponente useContext() aufruft, rendert sie weiterhin neu, wenn sich der Kontextwert ändert — unabhängig von React.memo.
HOC, der die Render-Ausgabe einer Komponente memoisiert. Überspringt Re-Rendering, wenn Props flach gleich dem vorherigen Rendering sind.
Vergleicht jede Prop mit Object.is(). Effektiv für Primitive. Objekte und Funktionen müssen dieselbe Referenz über Renderings hinweg beibehalten.
Wenn React.memo feststellt, dass Props gleich sind, gibt es die vorherige Render-Ausgabe zurück und überspringt den Aufruf der Komponentenfunktion.
Dieselbe Objekt-/Funktionsreferenz über Renderings hinweg beibehalten. Erforderlich damit React.memo korrekt mit nicht-primitiven Props funktioniert.
Ein Re-Rendering, bei dem die Ausgabe identisch mit dem vorherigen Rendering ist. React.memo verhindert diese, wenn sich Props logisch nicht geändert haben.
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}
In großen React-Bäumen mit komplexen Komponenten summieren sich unnötige Re-Renderings zu echten Leistungsproblemen — langsame Interaktionen, verlorene Frames, träge Animationen. React.memo ermöglicht es, gezielt bestimmte Komponenten am Re-Rendering zu hindern, teure Teilbäume stabil zu halten, während der Rest der App frei aktualisiert.
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.