React Memo ve useMemo nedir? Hangi durumlarda kullanılır?
Bugün react hookslarından useMemo ve React.memo‘yu inceleyeceğiz, örnekler yapacağız, nerede kullanılması gerektiğini bakıp hangi ihtiyaçlar için kullanılabileceğini tespit edeceğiz.
Öncelikle memoize kavramının anlamına bakalım.
Memoization, bir fonksiyon hesaplama yaparken daha önce yaptığı işlemi tutması ve böylece de her seferinde fonksiyonu çalıştırmayan bir yöntemdir. Örneğin faktöriyel hesaplayan bir fonksiyonumuz var, 12’nin her seferinde faktöriyelini alınması yerine bir kez alıp memoize edilirse tekrar çağrılma durumunda da fonksiyon çalışmaz ve otomatik bellekten çekilir.
Tanımı yaptıktan sonra Reactta bu yöntem nasıl kullanılıyor onu inceleyelim.
React.Memo
Örneğin bir header component ve altında da bir sayı artıran bir butonunuz olsun, butona her tıkladığımızda header tekrar render olacaktır. Aşağıdaki kodu inceleyelim
App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import { useState } from "react"; import Header from "./Header"; import "./styles.css"; export default function App() { const [number, setNumber] = useState(0); return ( <div className="App"> <Header title="Title" /> <button onClick={() => setNumber(number + 1)}>Increase</button> <p>{number}</p> </div> ); } |
Header.js
1 2 3 4 5 |
const Header = ({ title }) => { console.log("Header render"); return <h2>{title}</h2>; }; export default Header; |
her butona tıkladığımızda header render olacaktır

İşte bunun önüne geçebilmek için header componentini memoize etmemiz lazım, aşağıdaki gibi memoize edersek tekrar render olmayacaktır.
1 2 3 4 5 6 |
import { memo } from "react"; const Header = ({ title }) => { console.log("Header render"); return <h2>{title}</h2>; }; export default memo(Header); |

Kaynak kod: sandbox
Ne Zaman Kullanmalıyız?
Üstteki örnek nasıl kullanmamıza dair bir örnekti, bu tarz bir yaklaşımda ihtiyacımız yok tam tersi gereksiz bir performans kaybı olur propsların yoğun olduğu, fazla render olunan yerlerde kullanılması daha amacına uygun olur
useMemo Nedir?
useMemo hooksu dependecy liste bağlı olarak çalışır, listeden bir değer değiştiğinde fonksiyon çalışır ve cache’a atılır/memoize edilir.
Hangi Durumlarda Kullanılmalı?
usememo hooksu expensive fonksiyonlarımızı gereksiz yere render olmasını engeller, tamamen performans optimize etmek için kullanılan bir hook. basit, fazla işlem olmayan fonksiyonlarda kullanılmamalı ve amacınız tekrar render olmasın olmamalı react bunun garantisini vermiyor sadece performans üzerine kurgulanmalı.
Nasıl Çalışır
1 |
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); |
Örnek Proje
Statik bir kullanıcı listemiz olacak ve dropdown ile seçilen kullancının yaşını hesaplayacağız ayrıca bir de buton sayacımız olacak
App.js:
1 2 3 4 5 |
const users = [ { Id: 1, Name: "Okan", BirthDate: "09.10.1997" }, { Id: 2, Name: "Test", BirthDate: "01.05.1994" }, { Id: 3, Name: "Can", BirthDate: "03.12.1996" } ]; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
export default function App() { const [userId, setUserId] = useState(null); const [count, setCount] = useState(0); const computeAge = (userId) => { if (userId == null) return; console.log("rendering function"); var localizedDate = users.find((p) => p.Id == userId).BirthDate; var dateArray = localizedDate.split("."); var date = new Date(dateArray[2], dateArray[1], dateArray[0]); var diff = new Date(new Date().getTime() - date.getTime()); return Math.abs(diff.getUTCFullYear() - 1970); }; const ageAsMemoValue = computeAge(userId); return ( <div className="App"> <button onClick={() => setCount(count + 1)}>Counter</button> <p>{count}</p> <hr /> <select value={userId} onChange={(e) => setUserId(e.target.value)}> <option>Select...</option> {users.map((item) => { return ( <option key={item.Id} value={item.Id}> {item.Name} </option> ); })} </select> {userId ? ( <div> <p>year: {ageAsMemoValue}</p> <p>name: {users.find((p) => p.Id == userId).Name}</p> </div> ) : null} </div> ); } |
Dropdowndan bir kullanıcı seçtiğimiz zaman app.js render olacak ve kullancının yaşı hesaplanacak, fakat sayaç butonumuzu tıkladığımızda da yeniden render sonucu seçili kullanıcının yaşı yeniden hesaplanacak ve aşağıdaki gibi bir sonuç elde edeceğiz

Şimdi fonksiyon değerimizi memoize edelim.
1 |
const ageAsMemoValue = useMemo(() => computeAge(userId), [userId]); |

Sonuç
Görüldüğü gibi useMemo ile tekrar render sonucu gereksiz hesaplamalardan kaçınmış olduk, ama re-renderingi önlemek her zaman iyi bir şey değil, performansı geliştirirken bunu bedavaya yapmıyor kendisinin de bir maliyeti var, mesela memoize olan fonksiyon ilk çalıştığında bunu bellekde depolar, bu işlem büyükse mesela 5000 kayıt dönen bir fonksiyonsa ilk render maliyetli olacaktır, o yüzden projenizi ilk kez yaparken kullanmayın daha sonra maliyetli fonksiyonlarınızı optimize edebilirsiniz.
Kod: Sandbox
Başka bir yazıda görüşmek üzere 🙂