7 Mayıs 2020 Perşembe

React Native (12) - Hooks yapısı ve useMemo() ile methodun cache'ten yanıt vermesi.

Marhaba,
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/

React Native (11) - Hooks yapısı ve forwardRef, useImperativeHandle, useRef ile bir componentin bileşenlerine erişme

Marhaba,
bu yazımda React hooks  ile birlikte gelen forwardRef, useImperativeHandle, useRef  fonksiyonlarını inceleyeceğiz. 

React native ile uygulama geliştirirken bazen tüm ekranı render etmeden bir componetten başka bir componentin state'ini değitirerek sadce erişilen component'i render etmek isteyebilirsiniz. Bu gibi durumlarda referans kullanımı size yardımcı  olabilir.

Bu yazı için geliştirilen örnek uygulama da ToastMessageHooks adında  bir main component oluşturulur. Daha sonra CustomToastMessage adlı bir component oluşturularak girilen mesajı ekrana yazdıracak şekilde içeriği güncellenir.

ToastMessageHooks componenti içinde bir TextInput alanı ve buradan girelecek mesajı CustomToastMessage componentine gönderecek bir Button eklenir.
Toast mesajlarının erkana bastıracak CustomToastMessage componenti de yine  ana component(ToastMessageHooks) içinde çağrılır.

Durumu daha iyi kavrayabilmek için aşağıdaki adımları inceleyebilirsiniz. Yine github üzerinden CustomToastMessage ve CustomToastMessage componentlerini inceleyebilirsiniz.

ilk olarak react native ile bir proje oluşturun.
$ react-native init someProject

Terminal üzerinden projenin bulunduğu dizine gidin.
$ cd someProject

CustomToastMessage adında bir component oluşturun ve içeriğini aşağıdaki şekilde güncelleyin.

export const CustomToastMessage = forwardRef((props, ref) => {
  const [message, setMessage] = useState();
  const [isVisible, setIsVisible] = useState();

  const showToast = msg => {
    setIsVisible(true);
    setMessage(msg);
  };

  const hideToast = () => {
    setIsVisible(false);
    setMessage(null);
  };

  useImperativeHandle(ref, () => {
    return {
      show: showToast,
      hide: hideToast,
    };
  });

  if (!isVisible) {
    return null;
  }
  return (
    <View style={styles.toast}>
      <Text>{message}</Text>
    </View>
  );
});


ToastMessageHooks adında bir component oluşturn. İçeriği aşağıdaki gibi olmalıdır.

export const ToastMessageHooks = props => {
  const [desc, setDesc] = useState();

  const toastRef = useRef(null);

  const showToastMessage = d => {
    toastRef.current.show(d);
  };

  const hideToastMessage = () => {
    toastRef.current.hide();
  };

  return (
    <View style={styles.container}>
      <TextInput style={styles.input} onChangeText={d => setDesc(d)} />
      <AppButton        style={{marginTop: 10}}
        title="Show toast message"        onBtnPress={() => showToastMessage(`Message is ${desc}`)}
      />
      <AppButton        style={{marginTop: 10}}
        title="Hide toast message"        onBtnPress={() => hideToastMessage()}
      />
      <CustomToastMessage ref={toastRef} />
    </View>
  );
};


Son olarak her iki componentit de kapsayan tüm tanımlamaları kök dizindeki App.js dosyasına aşağıdaki gibi ekleyebilirsiniz.

import React, {
  Component,
  forwardRef,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import {StyleSheet, Text, TextInput, View} from 'react-native';
import {AppButton} from 'appComponent/Button';

export default class App extends Component {
  render() {
    return (
      <>
        <ToastMessageHooks />
      </>
    );
  }
}

export const CustomToastMessage = forwardRef((props, ref) => {
  const [message, setMessage] = useState();
  const [isVisible, setIsVisible] = useState();

  const showToast = msg => {
    setIsVisible(true);
    setMessage(msg);
  };

  const hideToast = () => {
    setIsVisible(false);
    setMessage(null);
  };

  useImperativeHandle(ref, () => {
    return {
      show: showToast,
      hide: hideToast,
    };
  });

  if (!isVisible) {
    return null;
  }
  return (
    <View style={styles.toast}>
      <Text>{message}</Text>
    </View>
  );
});

export const ToastMessageHooks = props => {
  const [desc, setDesc] = useState();

  const toastRef = useRef(null);

  const showToastMessage = d => {
    toastRef.current.show(d);
  };

  const hideToastMessage = () => {
    toastRef.current.hide();
  };

  return (
    <View style={styles.container}>
      <TextInput style={styles.input} onChangeText={d => setDesc(d)} />
      <AppButton        style={{marginTop: 10}}
        title="Show toast message"        onBtnPress={() => showToastMessage(`Message is ${desc}`)}
      />
      <AppButton        style={{marginTop: 10}}
        title="Hide toast message"        onBtnPress={() => hideToastMessage()}
      />
      <CustomToastMessage ref={toastRef} />
    </View>
  );
};

const styles = StyleSheet.create({
  toast: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'green',
    zIndex: 11,
    height: 60,
  },
  container: {
    flex: 1,
    paddingTop: 50,
    margin: 10,
  },
  input: {height: 40, borderWidth: 1, marginBottom: 10},
  paragraph1: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    color: 'blue',
  },
  paragraph2: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});


birkaç önemli nokta:
  • Hooks ile birlikte referans kullanabilmek için useRef import edilmelidir. ÖRN: import {useRef} from 'react';
  • useRef tanımı uygulamada aşağıdaki gibi tanımlanmıştır

    const toastRef = useRef(null);



    <CustomToastMessage ref={toastRef} />

  • Varsayılan durumda reactın compomentlerine useRef ile referans verilebilir.
  •  uygulamada CustomToastMessage componentinin hide() ve show(message) methodlarına aşağıdaki gibi erişilmiştir.

    const toastRef = useRef(null);
    
    const showToastMessage = d => {
      toastRef.current.show(d);
    };
    
    const hideToastMessage = () => {
      toastRef.current.hide();
    };

  • Ancak kendi yazdığınız bir compoment'e referans vermek isterseniz yazdığınız bo component'i forwardRef methodundan türetmeniz gerekmektedir.
  • forwardRef methodunu kullanmak için react'tan import etmek gerekir. ÖRN: import {forwardRef} from 'react';
  • forwardRef ile  CustomToastMessage componenti aşağıdaki gibi oluşturulmuştur.

    export const CustomToastMessage = forwardRef((props, ref) => {...}

  • Ayrıca forwardRef ile oluşturduğunuz referans'ın component dışından hangi bileşenlerine erişebileceğini de useImperativeHandle methoduyla belirtilmektedi.
  • Yine useImperativeHandle methodunu React'tan import edilerek dosyada çağrılabilir. ÖRN: import {useImperativeHandle} from 'react';
  • showToast ve hideToast methodlarını referanslı erişime açmak için aşağıdaki şekilde tanım yapılmıştır.

    useImperativeHandle(ref, () => {
      return {
        show: showToast,
        hide: hideToast,
      };
    });






github(state) : https://github.com/lvntyldz/tutorials/tree/10-react-hooks-useref/react-native-hooks-examples

github(projenin tamamı) : https://github.com/lvntyldz/tutorials/tree/master/react-native-hooks-examples

5 Mayıs 2020 Salı

React Native (10) - Hooks yapısı ve React.memo ile bir component'i cachelemek

Marhaba,
bu yazımda React ile birlikte gelen memo fonksiyonunu inceleyeceğiz. 
Bu fonksiyona parametre olarak verilen component,  ekran render olduğunda bir kez çalışmaktadır.
Daha sonra  component'in state ve props'unda bir değişiklik olmadığı sürece cache den değer dönülmektedir. Dolayısıyla gereksiz reRender işleminden kaçmak için bu yöntem kullanılabilir.

Geliştirilen örnek çalışmada, içinde başlangıç tarihi(yıl/ay)  ve bitiş tarihi(yıl/ay) olan bir ekran tasarlanmıştır. Ay ve Yıl bilgilerini başlıklarıyla birlikte ekrana basan "YearMonthViewer" adında bir component oluşturulmuştur. Yine aynı ekrana ay ve yıllara random değerler atayabilmek için  4 adet buton eklenmiştir.

Varsayılan durumda butonlara he basma işleminde state değişikliği olacağı için  ekranın tamamı  reRender olmaktadır.

Ancak YearMonthViewer componenti  export default React.memo(YearMonthViewer); şeklinde tanımlandığı için ana ekranda bu component'in kaç kez çağrıldığına bakılmaksızın  sadece değişikliğin bağlı olduğu component(YearMonthViewer) reRender edilmektedir.

Bu fonksiyonun kullanımmı oldukça basit olmasına rağmen uygulama performansına katkısı büyüktür.

Durumu daha iyi kavrayabilmek için aşağıdaki adımları inceleyebilirsiniz. Veya tam implementasyonu görmek için git üzerindeki kaynak kodları inceleyebilirsiniz.

ilk olarak react native ile bir proje oluşturun.
$ react-native init someProject

Terminal üzerinden projenin bulunduğu dizine gidin.
$ cd someProject

YearMonthViewer adında bir component oluşturun ve dosya içeriğini aşağıdaki şekilde güncelleyin.

import React from 'react';
import {StyleSheet, Text} from 'react-native';

const styles = StyleSheet.create({
  paragraph2: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    color: 'red',
  },
});

function YearMonthViewer({title, year}) {
  console.warn(`YearMonthViewer - title : ${title} - year : ${year}`);
  return (
    <Text style={styles.paragraph2}>
      {title} : {year}
    </Text>
  );
}

export default React.memo(YearMonthViewer);


cacheleme yapan kısım  : export default React.memo(YearMonthViewer);
React.memo kısmını kaldırarak test ederseniz her butona bastığınızda YearMonthViewer componenti ana ekranda çağrıldığı kadar(4 kez) render edilecektir.  Mevcut durumda ise her butona basıldığında YearMonthViewer componenti sadece 1 kez render edilmektedir.

NOT: ReRender işlemlerinin gözle farkedilebilmesi için YearMonthViewer componentine warn seviesinde log eklenmiştir.

Üstte tanımlanan component'ide kapsayan bir ekran oluşturmak için  DateRangeHooks adında bir component oluşturun.
İçinde tarih aralıkları ve güncelleme butonları bulunan Component aşağıdaki gibi tanımlanmalıdır.

import React, {useState} from 'react';
import {StyleSheet, View} from 'react-native';
import {AppButton} from 'appComponent/Button';
import YearMonthViewer from 'appComponent/YearMonthViewer';
import {random} from 'appUtil';

export const DateRangeHooks = props => {
  const [startYear, setStartYear] = useState(2020);
  const [endYear, setEndYear] = useState(2050);
  const [startMonth, setStartMonth] = useState(1);
  const [endMonth, setEndMonth] = useState(5);

  return (
    <View style={styles.container}>
      <View style={styles.grouping}>
        <YearMonthViewer title="Start Year" year={startYear} />
        <YearMonthViewer title="End Year" year={endYear} />
      </View>

      <View style={styles.grouping}>
        <YearMonthViewer title="Start Month" year={startMonth} />
        <YearMonthViewer title="End Month" year={endMonth} />
      </View>

      <View style={styles.grouping}>
        <AppButton          style={styles.startDateBtn}
          title="change start Year"          onBtnPress={() => setStartYear(random(2000, 2020))}
        />

        <AppButton          style={{marginTop: 5}}
          title="change end Year"          onBtnPress={() => setEndYear(random(2020, 2050))}
        />
      </View>

      <View style={styles.grouping}>
        <AppButton          style={styles.startDateBtn}
          title="change start month"          onBtnPress={() => setStartMonth(random(1, 12))}
        />

        <AppButton          style={{marginTop: 5}}
          title="change end month"          onBtnPress={() => setEndMonth(random(1, 12))}
        />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    margin: 10,
  },
  input: {height: 40, borderWidth: 1, marginBottom: 10},
  paragraph1: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    color: 'blue',
  },
  grouping: {
    flex: 1,
    maxHeight: 100,
    flexDirection: 'row',
  },
  startDateBtn: {marginTop: 5, backgroundColor: 'skyblue'},
});


index.js dosyasında render methodunda aşağıdaki şekilde tasarladığınız ekranı aşağıdaki şekilde çağırarak test edebilirsiniz.

render() {
  return <DateRangeHooks/>;
}


github(state) : https://github.com/lvntyldz/tutorials/tree/9-react-hooks-usememo/react-native-hooks-examples

github(projenin tamamı) : https://github.com/lvntyldz/tutorials/tree/master/react-native-hooks-examples

React Native (9) - Hooks ve ClassComponent ile koşullu useEffect ve componentDidUpdate kullanımı

Marhaba,
bir önceki paylaşımımda hooks ile birlikte gelen useEffect'e değinmiştim. Bu yazımda ise her state yada prop değişikliğinde değilde sadece istediğimiz bir state'in değişmesi durumunda useEffect methodunu çalıştıracağız. Dolayısıyla daha optimal bir kod yazarak gereksiz render işleminden kurtulmuş olacağız.

ClassComponent yapısında ise aynı durumu ele alarak  componentDidUpdate in içerisinde sadece beklenen state değişikliği yapılması case'inde console'a log yazdıracağız.

Bu paylaşımda konu,  ShipmentDescValue ve ShipmentDescValueHooks componentleri üzerinden örneklendirilmiştir. github üzerinden bu componentleri inceleyebilirsiniz.

ShipmentDescValue ve ShipmentDescValueHooks componentlerinde product ve shipment senaryoları ele alınarak product itemCount değiştiğinde ekrana bir log yazdırılmıştır. Eğer componentDidUpdate ve useEffect methodlarında bir tanımlama yapılmazsa(varsayılan durumda) shipmentDesc alanı değiştiğinde de itemCount ta bir değişiklik olmuş gibi yine aynı log görülmektedir.  Ancak sadece itemCounte değiştiğinde uygulamanın log yazmasını sağlayan içerik aşağıda paylaşılmıştır.

ÖRNEK Product Objesi :
{title: 'iPhone 11',itemCount: 2,price: 1500}

Aşağıdaki useEffect tanımına göre useEffect methodu sadece 1 kere component render edilirken çalışır.
useEffect(() => {  console.warn('Use Effect!');}, []);

Eğer aşağıdaki gibi useEffect fonktisyonuna hiç parametre geçmezsek tüm state değişikliklerinde çalışır.
useEffect(() => {  console.warn('Use Effect!');});

Buradaki tanıma göre ise sadece state objesi üzerinde değişiklik olursa  çalışır. TextInput üzerinde yapılan değişikliklerden etkilenmez.
useEffect(() => {  console.warn('Use Effect!');}, [state]);

Eski yapıdaki kontrolü ise şöyledir:
componentDidUpdate(prevProps, prevState) {
  if (prevState.itemCount !== this.state.itemCount) {
    console.warn('Product Item Count Update: ', this.state.itemCount);
  }
}

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, useEffect, useState} from 'react';
import {StyleSheet, Text, TextInput, View} from 'react-native';
import {AppButton} from 'appComponent/Button';

export default class App extends Component {
  render() {
    return (
      <>
        <ShipmentDescValue />
        <ShipmentDescValueHooks />
      </>
    );
  }
}

export class ShipmentDescValue extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: 'iPhone 11',
      itemCount: 2,
      price: 1500,
      shipmentDesc: '',
    };
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.itemCount !== this.state.itemCount) {
      console.warn('Product Item Count Update: ', this.state.itemCount);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.paragraph2}>
          state : {JSON.stringify(this.state)}
        </Text>
        <TextInput          onChangeText={val => this.setState({shipmentDesc: val})}
          style={styles.input}
        />
        <AppButton          style={{marginTop: 10}}
          title="update count"          onBtnPress={() =>
            this.setState({itemCount: this.state.itemCount + 1})
          }
        />
      </View>
    );
  }
}

export const ShipmentDescValueHooks = props => {
  const [shipmentDesc, setShipmentDesc] = useState('');
  const [state, setState] = useState({
    title: 'iPhone 11',
    itemCount: 2,
    price: 1500,
  });

  useEffect(() => {
    console.warn('Use Effect!');
  }, [state]);

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph1}>state : {JSON.stringify(state)}</Text>
      <Text style={styles.paragraph1}>
        desc : {JSON.stringify(shipmentDesc)}
      </Text>
      <TextInput        onChangeText={val => setShipmentDesc(val)}
        style={styles.input}
      />
      <AppButton        style={{marginTop: 10}}
        title="update count"        onBtnPress={() => setState({...state, itemCount: state.itemCount + 1})}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    margin: 10,
  },
  input: {height: 40, borderWidth: 1, marginBottom: 10},
  paragraph1: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    color: 'blue',
  },
  paragraph2: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});



github(state) : https://github.com/lvntyldz/tutorials/tree/8-react-hooks-useeffect-conditional/react-native-hooks-examples

github(projenin tamamı) : https://github.com/lvntyldz/tutorials/tree/master/react-native-hooks-examples

4 Mayıs 2020 Pazartesi

React Native (8) - Hooks ve ClassComponent ile useEffect, componentDidMount ve componentDidUpdate kullanımı

Marhaba,
bu yazımda sizlere React Hooks ile birlikte gelen useEffect kullanımını paylaşacağım.
Bilindiği üzere react ClassComponent yapısındaki yaşam döngüsünde component oluşturulduktan sonra componentDidMount() methodu devreye girerdi. Component her update işleminden sonra da componentDidUpdate() methodu çağrılmaktadır.

FunctionalComponent(Hooks) yapısında ise her iki methodun yerine de useEffect methodu çağrılmaktadır.
Yani bir component ekranda gösterildiğinde(mount) ve bu componentin değerleri güncellendiğinde yine useEffect methodu çağrılmaktadır.

Aşağıda product objesi üzerinden title alanını değiştirerek Class yapısında componentDidUpdate() methodunun Hooks yapısında ise useEffect methodunun çağrıldığı görülmektedir.

ÖRNEK Product Objesi :
{title: 'iPhone 11',itemCount: 2,price: 1500}

ProductTitleValue ve ProductTitleValueHooks componentleri üzerinden useEffect kullanımı anlatılmıştır. github üzerinden projeye erişerek bu componentleri inceleyebilirsiniz.


Ayrıca 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, useEffect, useState} from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {AppButton} from 'appComponent/Button';

export default class App extends Component {
  render() {
    return (
      <>
        <ProductTitleValue />
        <ProductTitleValueHooks />
      </>
    );
  }
}

export class ProductTitleValue extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: 'iPhone 11',
      itemCount: 2,
      price: 1500,
    };
  }

  componentDidMount() {
    console.warn('Did mount!');
  }

  componentDidUpdate(prevProps, prevState) {
    console.warn('Did Update prevProps: ', prevProps);
    console.warn('Did Update prevState: ', prevState);
  }

  handleTitleChange = () => {
    this.setState({title: 'xiaomi mi 10 pro'});
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.paragraph2}>
          state : {JSON.stringify(this.state)}
        </Text>
        <AppButton          style={{marginTop: 10}}
          title="update title"          onBtnPress={() => this.handleTitleChange()}
        />
      </View>
    );
  }
}

export const ProductTitleValueHooks = props => {
  const [state, setState] = useState({
    title: 'iPhone 11',
    itemCount: 2,
    price: 1500,
  });

  const handleTitleChange = () => {
    setState({...state, title: 'xiaomi mi 10 pro'});
  };

  useEffect(() => {
    console.warn('Use Effect!');
  });

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph1}>state : {JSON.stringify(state)}</Text>
      <AppButton        style={{marginTop: 10}}
        title="update title"        onBtnPress={() => handleTitleChange()}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    margin: 10,
  },
  input: {height: 40, borderWidth: 1, marginBottom: 10},
  paragraph1: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    color: 'blue',
  },
  paragraph2: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});


özet:

  • ClassComponent yapısı
    • component mount işleminden sonra "componentDidMount()" methodu çağrılmaktadır. Yani varsayılanda render dan sonra bu method çağrılır.
    • component güncelleme işleminden sonra ise "componentDidUpdate()" methodu çağrılır. 


  • FunctionalComponent(Hooks) Yapısı
    • hem componentDidMount() hemde componentDidUpdate()'in çağrıldığı yerlerde useEffect() methodu çağrılır.
    • React tan import edilip projede fonksiyon olarak çağrılarak kullanılır.  import {useEffect} from 'react';


github(state) : https://github.com/lvntyldz/tutorials/tree/7-react-hooks-useeffect/react-native-hooks-examples

github(projenin tamamı) : https://github.com/lvntyldz/tutorials/tree/master/react-native-hooks-examples