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

React Native (7) - Hooks ve ClassComponent ile state güncelleme esnasında geçmiş değer(previous state) kontrolü

Marhaba,
bu yazımda yine React Native ile state object kullanırken bir önceki state değerini kontrol etmeyi inceleyeceğiz. Yine product objesi üzerinden örnekler yapılacaktır. Bu kez itemCount değeri değil price değeri hem ClassComponent yapısıyla hemde Hooks yapısıyla güncellenecektir.

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

ProductPriceValue ve ProductPriceValueHooks componentleri ile örnek açıklanmıştır. Github üzerinde bu componentleri 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} from 'react';
import {Routes} from 'appEnum';
import {StyleSheet, Text, View} from 'react-native';
import {AppButton} from 'appComponent/Button';

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

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

  handlePriceChange = () => {
    this.setState((prevState, props) => {
      console.warn('prevState : ', prevState);
      return {
        price: prevState.price + 101,
      };
    });
  };

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

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

  const handlePriceChange = () => {
    setState(prevState => {
      console.warn('prevState : ', prevState);
      return {...prevState, price: prevState.price + 100};
    });
  };

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph1}>state : {JSON.stringify(state)}</Text>
      <AppButton        style={{marginTop: 10}}
        title="increase item count"        onBtnPress={() => handlePriceChange()}
      />
    </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',
  },
});


açıklamalar :

  • ClassComponent yapısında setState methoduna parametre olarak  geçilen bir fonksiyon ile prevState değeri alınabilmektedir.
  • Üstteki örnekte prevState değeri alındıktan sonra price güncellenerek yeni değer state'e kaydedilmiştir.
  • ClassComponent yapısında setState methoduna parametre olarak fonksiyon geçilerek prevState ile birlikte props değeri de alınabilmektedir.
  • const [state, setState] = useState();
    • Hooks yapısında useState ten alınan setState fonksiyonuna parametre olarak fonksiyon geçerek mevcut state değerlerine erişilebilir.
    • Bu sayede üstteki örnekte  eski değere 100 ekleyerek product price  güncellenmektedir.
    • ÖRN: setState(prevState => {return {...prevState, price: prevState.price + 100};});

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

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

React Native (6) - Hooks ve ClassComponent ile çoklu state object güncelleme

Marhaba,
bu yazımda yine React Native ile multi state kullanımını inceleyeceğiz. Ancak bir önceki yazıdan farklı olarak  burada bir objenin içindeki element güncellenecektir.  Title,ItemCount ve Price değerlerine sahip olan bir product objesi örneklenecektir. title ve price'ta bir değişiklik yapmadan hooks ve ClassComponent ile itemCount değiştirmenin nasıl olacağı paylaşılmaktadır.

ProductItemCount ve ProductItemCountHooks componentleri üzerinde örnekler yapılmıştır. github üzerinden bu componentlerin tamamını inceleyebilirsiniz.

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

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

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

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

  handleItemCountOnPress = () => {
    const itemCountValue = (this.state.itemCount += 1);
    this.setState({itemCount: itemCountValue});
  };

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

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

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph1}>state : {JSON.stringify(state)}</Text>
      <AppButton        style={{marginTop: 10}}
        title="increase item 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',
  },
});



Önemli notlar:
  • ClassComponent örneğinde itemCount değerini güncellemek için react tan gelen ve  class içerisindeki state'i güncellemek amacıyla geliştirilen  setState methodu kullanılmıştır.
  • ClassComponent yapısında state güncellemesi yaparken  setState methoduna güncellenecek element ve bu elementin değeri parametre olarak bir obje içerisinde verilmelidir. ÖRN:   this.setState({itemCount: itemCountValue})
  • Hooks yapısında üstteki örnekte varsayılan state tanımlaması aşağıdaki gibi yapışmıştır : const [state, setState] = useState({title: 'iPhone 11',itemCount: 2, price: 1500})
    •  Buradaki tanıma göre useState ten alınan setState methodunu kullandığınızda state objesi ezilir. Dolayısıyla title ve price değerleri kaybolur.
    •  Bu durumu aşmak için ise önce (...state) tanımıyla mevcutta bulunan state değeri ele alınır daha sonra eldeki state üzerinden itemCount değerinin güncellemesi yapılır. ÖRN:setState({...state, itemCount: state.itemCount + 1})


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

React Native (5) - Hooks ve ClassComponent ile çoklu state kullanımı

Marhaba,
bu yazımda React Native ile multi state kullanımını inceleyeceğiz.
Counter örneğini ele alarak ilerlenilecektir.
İlk olarak reactın eski versiyonlarında gelen ClassComponent yapısıyla  startCount ve endCount değerlerini ayrı ayrı güncelleyip güncel değerleri ekranda gösterilecektir.

ikinci olarak ise Hook yapısıyla birlikte gelen useState methodu aracılığıyla yine aynı değerler farklı bir component içinde güncellenip ekrana basılacaktır.

ClassComponent yapısını gösteren "RangeCounter" component'i,  Hooks yapısı için ise "RangeCounterHooks" oluşturulacaktır.

Aşağıdaki adımları takip ederek sizde kendi çalışma ortamında örneği 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} from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {AppButton} from 'appComponent/Button';

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

export class RangeCounter extends Component {
constructor(props) {
super(props);
this.state = {
start: 0,
end: 0,
};
}

handleStartOnPress = () => {
const startValue = (this.state.start += 1);
this.setState({start: startValue});
};

handleEndOnPress = () => {
const endValue = (this.state.end += 1);
this.setState({end: endValue});
};

render() {
return (
<View style={styles.container}>
<View style={styles.groupping}>
<Text style={styles.paragraph1}>
start value : {this.state.start}
</Text>
<Text style={styles.paragraph2}>end value : {this.state.end}</Text>
</View>
<View style={styles.groupping}>
<AppButton
style={{marginTop: 10}}
title="increase start count"
onBtnPress={() => this.handleStartOnPress()}
/>

<AppButton
style={{marginTop: 10}}
title="increase end count"
onBtnPress={() => this.handleEndOnPress()}
/>
</View>
</View>
);
}
}

export const RangeCounterHooks = props => {
const [start, setStart] = useState(0);
const [end, setEnd] = useState(0);

return (
<View style={styles.container}>
<View style={styles.groupping}>
<Text style={styles.paragraph1}>start value : {start}</Text>
<Text style={styles.paragraph2}>end value : {end}</Text>
</View>
<View style={styles.groupping}>
<AppButton
style={{marginTop: 10}}
title="increase start count"
onBtnPress={() => setStart(start + 1)}
/>

<AppButton
style={{marginTop: 10}}
title="increase end count"
onBtnPress={() => setEnd(end + 1)}
/>
</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',
},
paragraph2: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
groupping: {
flexDirection: 'row',
},
});



Önemli kısımlardan bazıları:
  • ClassComponent yapısında start ve end değerleri constructor da bir state oluşturlarak tutulur.
  • Hooks yapısında ise useState methodu ile Hooks üzerinde start ve end değerleri tutulur.
  • ClassComponent yapısında this.setState({start: startValue}) şeklide state üzerinden güncelleme yapılır.
  • Hooks yapısında ise useState ten dönen setStart(<YENI_DEGER>) şeklinde state değişikliği yapılır.

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