Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

React'te bir component'in gereksiz yere tekrar render olmasını engellemek için React.memo'yu ne zaman kullanmalıyım?

thecoder

Üye
Katılım
14 Mart 2026
Mesajlar
37
Merhaba arkadaşlar, bugün sizlerle React'te performans optimizasyonu yaparken sıkça karşımıza çıkan, bazen de gereksiz yere kullanıp "acaba doğru mu yapıyorum?" dedirten bir konuyu, React.memo'yu konuşacağız. Özellikle büyük uygulamalarda, bir component'in gereksiz yere render olması, uygulamanın yavaşlamasına ve kullanıcı deneyiminin bozulmasına neden olabiliyor. Bu hatayı ilk gördüğümde, "State'im aynı, neden yeniden render oluyor bu?" diye kafayı yemiştim. İşte benim bu süreçte öğrendiğim, React.memo'yu ne zaman kullanıp ne zaman kullanmamamız gerektiği.

🔥 Karşılaştığım Sorun
Bir projede, ana sayfada bir filtreleme paneli ve bu filtreye bağlı yüzlerce ürünü listeleyen bir component vardı. Filtre state'i değiştiğinde, mantıken sadece ürün listesi component'i render olmalıydı. Ancak React Dev Tools'un "Highlight updates when components render" özelliğini açtığımda gördüm ki, filtre panelindeki her bir buton, input bileşeni de yeniden render oluyordu! Bu, props'ları hiç değişmeyen, saf görünümlü bileşenler için büyük bir performans kaybıydı.

⚛️ React.memo Nedir ve Nasıl Çalışır?
React.memo, bir Higher Order Component (HOC)'tir. Bir fonksiyonel component'i alır, onu hafızaya (memoization) alınmış yeni bir component olarak döndürür. Bu yeni component, kendisine gelen props'ları bir önceki render ile karşılaştırır. Eğer props'lar shallow comparison (sığ karşılaştırma) ile aynıysa, React bir önceki render sonucunu tekrar kullanır ve component'i yeniden render etmez.

Temel kullanımı şöyle:
JavaScript:
import React from 'react';

const MyExpensiveComponent = ({ title, items }) => {
  // Ağır hesaplamalar yapan bir component
  console.log('MyExpensiveComponent rendered!');
  return (
    <div>
      <h2>{title}</h2>
      <ul>{items.map(item => <li key={item.id}>{item.name}</li>)}</ul>
    </div>
  );
};

export default React.memo(MyExpensiveComponent);

✅ React.memo'yu KULLANMAN Gereken Durumlar
1. Props'ları Sık Değişmeyen Saf Bileşenler: Bir component, aynı props ile defalarca render ediliyorsa (örneğin, bir sidebar item'ı, bir başlık, bir statik kart) ideal adaydır.
2. Render'ı Gerçekten Pahalı Bileşenler: İçinde ağır hesaplamalar, harici veri işlemleri veya çok fazla alt bileşen (büyük liste) olan component'ler. Burada memo, render maliyetinden daha ucuz kalır.
3. Üst Bileşen Sık Render Oluyorsa: Üst component (parent) sık sık state değişikliği yaşıyor ama alt component'e (child) ilettiği props değişmiyorsa, alt component'i memo ile sarmalamak çok faydalıdır.

❌ React.memo'yu KULLANMAMAN Gereken Duramlar
1. Component Zaten Basit ve Hafifse: Eğer component'in kendisi çok basitse (bir buton, bir ikon), memo'nun props karşılaştırma maliyeti, yeniden render maliyetinden daha yüksek olabilir. Premature optimization yapmaktan kaçının.
2. Props'ları Neredeyse Her Zaman Değişiyorsa: Eğer component her seferinde farklı props alıyorsa, memo hiçbir işe yaramaz çünkü her seferinde render edilmesi gerekecektir. Hatta karşılaştırma için ekstra bir maliyet getirir.
3. Props Olarak Fonksiyon veya Nesne Alıyorsa (Dikkat!): Bu en sık düşülen tuzak! React'te fonksiyonlar ve nesneler referans tiptedir. Üst component her render olduğunda, onClickHandler gibi bir fonksiyon prop'u yeni bir referans ile oluşturulur. Bu da memo'nun "props'lar değişti" demesine ve bileşeni yeniden render etmesine neden olur. Çözüm: useCallback veya useMemo.

🔧 useCallback ile Birlikte Kullanım (Kritik Kombinasyon)
İşte benim kullandığım en temiz çözüm. Eğer memo'lu bir componente fonksiyon geçiriyorsanız, o fonksiyonu mutlaka `useCallback` ile sarmalayın.
JavaScript:
import React, { useState, useCallback } from 'react';
import MemoizedChild from './MemoizedChild';

const ParentComponent = () => {
  const [count, setCount] = useState(0);
  const [filter, setFilter] = useState('');

  // Bu fonksiyon, count değişmediği sürece aynı referansı korur.
  const handleReset = useCallback(() => {
    setFilter('');
  }, []); // Bağımlılık dizisi boş, çünkü hiçbir state/prop'a bağlı değil.

  // Bu fonksiyon, filter değiştiğinde yeniden oluşturulur.
  const handleFilterChange = useCallback((newFilter) => {
    setFilter(newFilter);
  }, []);

  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>Arttır: {count}</button>
      {/ MemoizedChild, handleReset prop'u değişmediği için count artışından ETKİLENMEZ /}
      <MemoizedChild onReset={handleReset} filterValue={filter} onFilterChange={handleFilterChange} />
    </div>
  );
};

Sonuç olarak, React.memo güçlü bir optimizasyon aracıdır ama her bileşene uygulanacak sihirli bir değnek değildir. Kullanmadan önce "Bu bileşen gerçekten pahalı mı render oluyor?" ve "Props'ları gerçekten stabil kalabiliyor mu?" sorularını kendinize sorun. Profiler aracını kullanarak ölçüm yapmak da her zaman en doğru yoldur.

Siz React'te performans için hangi yöntemleri kullanıyorsunuz? `useMemo` ile `React.memo` arasındaki farkları nasıl değerlendiriyorsunuz? Ya da memo kullanırken sizi en çok hangi tuzaklar zor durumda bıraktı? Yorumlarda tartışalım!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri