bu yazımda React hooks ile birlikte gelen useMemo fonksiyonunu inceleyeceğiz. React Native ile geliştirilen uygulamada bir ekranda birden fazla değişkenin state değerinde değişiklik yapılıyorsa varsayılan olarak her bir değişiklikte ekranın tamamı render edilir.
Eğer bu ekranın bağımlı olduğu methodlar fazla zaman alacak işler yapıyorsa ekranın yanıt verme süresi de buna bağlı olarak uzayabilir. Hooks yapısında bu durumunu çözümü için useMemo methodu kullanılmaktadır. useMemo methoduna cache leyeceği methodu ve hangi değişkenlerin değeri güncellendiğinde yeniden çalışacağı bildirilerek gereksiz yere re-render işleminden kaçılabilir.
Bu yazı için geliştirilen örnek uygulamada bir Product'ın price(fiyat) ve count(adet/miktar) değerlerini tutacak şekilde CounterHooks adında bir component oluşturulmuştur. Ekrana price
ve count değerlerini değiştirecek 2 adet button eklenmiştir. Bu butonlar kullanılarak fiyat değiştikçe ekran hemen render edilmektedir. Ancak sayı(count) değiştiğinde girilen delay time kadar bekleme yapılıp ekran öyle render edilmektedir. Eğer burada useMemo methodu kullanılmasaydı fiyat arttığında da state değişikliği olacağı için gereksiz yere calculateColor(...) methodu çağrılarak delay time kadar render da bekleme olacaktır.
Durumu daha iyi kavrayabilmek için aşağıdaki adımları inceleyebilirsiniz. Veya git üzerinden daha detaylı CounterHooks component'ini inceleyebilirsiniz.
Aşağıdaki adımları takip ederek kendi projenizde uygulayabilirsiniz.
ilk olarak react native ile bir proje oluşturun.
$ react-native init someProject
|
Terminal üzerinden projenin bulunduğu dizine gidin.
$ cd someProject
|
kök dizindeki App.js dosyasının içeriğini aşağıdaki şekilde güncelleyin.
import React, {Component, useState, useMemo} from 'react'; import {View, StyleSheet, Text} from 'react-native'; import {AppButton} from 'appComponent/Button'; export default class App extends Component { render() { return <CounterHooks />; } } export const CounterHooks = () => { const [count, setCount] = useState(0); const [price, setPrice] = useState(1000); const delay = millisecond => { const startPoint = new Date().getTime(); while (new Date().getTime() - startPoint <= millisecond) { console.warn('sleeping...'); } }; const calculateColor = () => { delay(1500); return count % 2 === 0; }; const isBlue = useMemo(calculateColor, [count]); return ( <View style={styles.container}> <Text style={styles.paragraph}> {isBlue ? 'blue' : 'yellow'} color selected </Text> <AppButton style={[styles.btn, {backgroundColor: isBlue ? 'blue' : 'yellow'}]} title={`increment Count - (${count})`} onBtnPress={() => setCount(c => c + 1)} /> <AppButton style={styles.btn} title={`increment Price - (${price})`} onBtnPress={() => setPrice(c => c + 5)} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, margin: 10, top: 50, }, btn: {margin: 10, backgroundColor: 'skyblue'}, paragraph: { fontSize: 14, maxHeight: 60, margin: 10, padding: 0, }, }); |
count değerinde bir değişiklik olmadığı sürede useMemo cache ten yanıt vererek methodun içindeki hesaplamayı yeniden çalıştırmaz.
const isBlue = useMemo(calculateColor, [count]); |
Kendi bilgisayarınızda yaptığınız çalışmada useMemo methodunu kaldırarak price değişikliği durumunda da ekranın yavaş render edildiğini görebilirsiniz.
1.5 sn bekleyerek methoddan değer dönülmektedir.
const calculateColor = () => { delay(1500); return count % 2 === 0; }; |
"Increment Count" ve "Increment Price" butonlarına basarak aradakı hız farkını gözlemleyebilirsiniz.
github(state) : https://github.com/lvntyldz/tutorials/tree/11-react-hooks-usememo/react-native-hooks-examples
github(projenin tamamı) : https://github.com/lvntyldz/tutorials/tree/master/react-native-hooks-examples
kaynak : https://usehooks.com/useMemo/