react etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
react etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

9 Haziran 2020 Salı

JHipster-1 (JHipster nedir ? Ne işe yarar ?)

Merhaba,
bu yazımda JHipster(Java Hipster) hakkında bir kaç bilgi aktaracağım. Esasen şirket içi eğitim için aldığım kısa notları derleyerek  buradan paylaşacağım.

JHipster bir java geliştirme platformudur. Bir çok geliştirici(developer) aynı şeyleri tekrar tekrar yazmayım diye kendine bir şablon proje(boilerplate) oluşturmayı denemiştir. Github üzerinde beğenilen(star) ve indirme  oranı yüksek olan   birçok dil ve library ile temelleri oluşturulmuş çokça tepmplate proje de bulunmaktadır.  Bu çalışmaların yapılmasında ve bu repoların oluşturulmasındaki maksat ayrnı işleri tekrarlı bir şekilde yapmaktan kaçmaktır. Özetle amaç zaman kaybının önüne geçmektir.

JHipster community de buradaki ihtiyaca çözüm üretmek adına Java ile geliştirme yapan developer'ların sıfırdan proje yaparken ilk adımları hızlı olması adına belli teknolojileri ve kofigurasyonları bir araya getirerek bir şablon proje  hazırlamışlardır. Buradaki paketin içinden ihtiyacınız olanları seçerek kendinize bir geliştirme ortamı hazırlayabilmektesiniz.

Nasıl bir şablon projeden bahsediyorum  örnek olarak açıklamaya çalışayım; mesela oluşturacağınız bir çok yeni projede bir login ekranı kullanmak isteyebilirsiniz. Yada projede  database kullanacaksanız bir migration(değiişikliklerin uygulanması) yapısına ihtiyacınız olacaktır. Yine bir loglama alt yapısına ihtiyac duymanız kuvvetle muhtemeldir. Dolayısıyla bu ve benzeri kofigürasyonlar için her projede yeniden efor sarfetmemek adına kendiniz bir boilerplate proje oluşturabilirsiniz yada bu işi bir standart üzerine inşa etmiş JHipster tan faydalanabilirsiniz. JHipster tam olarak üstte bahsettğim teknolojileri bir araya getirerek size ilk ayarları yapılmış bir proje sunmaktadır.

JHipster üstte paylaştıklarıma ek olarak şağıdaki tanım ve teknolojileri de destekler.

Core
- Java 
- SpringBoot
- SpringSecurity
- SpringMVCRest
- Jackson
- internationalization
- profile(dev,prod)

Frontend
- React With Redux (Redux ile birlikte)
- Angular
- Vue
- Sass
- css
- bootstrap

Database
- mongoDB
- Couchbase 
- Relational DB(H2,MySQL,..)

Cache
- Ehcache
- Hazelcast
- Caffeine

Deployment
- heroku
- openshift
- aws

Build
- maven
- gradle
- grunt
- yeoman
- webpack
- git

JHipster bu kadar teknolojinin hepsini kullanabilir. Ancak CLI üzerinden proje olulturmak istediğinizde veya web arayüzü üzerinden ilerlerken ihtiyacınıza göre üstteki listeden eleme yada ekleme yapabilirsiniz. ÖRN: Microservis için bir frontend framework'e ihtiyacınız olmayacağı gibi monolitic uygulamada da sadece angular'ı veya react'ı seçerek te ilerleyebilmektesiniz.

JHipster ile çalışmaya başlamak için bilgisayarnızda aşağıdaki programların kurulu olması gerekmektedir.
- Java
- NodeJs
- JHipster (npm install -g generator-jhipster)

7 Mayıs 2020 Perşembe

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

30 Nisan 2020 Perşembe

React Native (3) - Hooks ve ClassComponent ile stateden değer almak

Merhaba,
bu yazımda react native ile state te değer tutmayı paylaşacağım. ClassComponent yapısıyla ve Hooks yapısıyla state üzerindeki değeri okuyarak ekrana yazdıracağız.

Aşağıdaki adımları takip ederek hem hooks tan hemde ClassComponent ten message içeriğini alarak ekrana yazdırmayı görebilirsiniz.

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';

export const MessagesHooks = props => {
  const [message, setMessage] = useState(
    'Hello from MessagesHooks - This is state message',
  );

  return (
    <View style={styles.hook}>
      <Text style={styles.paragraph}>{message}</Text>
    </View>
  );
};

export class Messages extends Component {
  constructor(props) {
    super(props);
    this.state = {
      message: 'Hello from Messages - This is state message',
    };
  }

  render() {
    return (
      <View style={styles.message}>
        <Text style={styles.paragraph}>{this.state.message}</Text>
      </View>
    );
  }
}
export default class App extends Component {
  render() {
    return (
      <View style={styles.main}>
        <Messages />
        <MessagesHooks />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  main: {
    flex: 1,
  },
  hook: {
    flex: 1,
    backgroundColor: 'skyblue',
  },
  message: {
    flex: 1,
    backgroundColor: 'steelblue',
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    color: 'red',
  },
});


birkaç önemli nokta:

  • ClassComponent ile state oluştururken bir constructor tanımlanır ve bu constructor içinde state oluşturulur.
  • ClassComponent'in içinden yada render methodundan this.state diyerek state teki değerler okunabilir.
  • Hooks yapısında state kullanabilmek için ilk olarak React tan useState methodunu import etmek gerekmektedir.
  • useState import edildikten sonra  hooks methodunun içinde const [message, setMessage] = useState(...); şeklinde tanımlamayla message değerinin state te tutulacağını ve bunun setMessage methoduyla güncelleneceği belirtilir.
  • Hooks ile state kullanımı yapılırken  useState fonksiyonuna verilen parametre state' in inital değeri olmaktadır. useState("varsayilan değer");

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






React Native (1) - Hooks ve ClassComponent ile ayrı ayrı HelloWorld uygulaması

Herkese merhaba,
bu yazımda react 16.8 ile birlikte gelen hooks yapısına kısa bir giriş yapacağız.
Önce ekrana "Hello World" yazan bir classComponent oluşturacağız ardından da aynı işi yapan Hooks fonksiyonunu yazacağız.

NOT: vakit bulursam hooks yapısıyla alakalı birkaç  yazı daha yazıp bir seri haline getirerek github üzerinde paylaşacağım.

Proje yapısı aşağıdaki şekilde olacaktır.
├── package.json
└── src
    ├── screens
    │   ├── Home
    │   │   ├── Class
    │   │   │   └── index.js
    │   │   └── Hooks
    │   │       └── index.js
    │   └── package.json
    └── wrapper
        └── index.js


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

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

src/screens adında bir dizin oluşturun. Ardından burada bir package.json dosyası oluşturun.
$ mkdir src/screens/ && touch package.json

package.json dosyasının içeriğini aşağıdaki şekilde güncelleyin.
{
  "name": "appScreen"
}

touch ile HomeHooks fonksiyonunu tanımlamak için Hooks dizininde index.js adında bir dosya oluşturun
$ touch src/screens/Home/Hooks/index.js

index.js dosyasının içeriğini aşağıdaki şekilde güncelleyin.
import * as React from 'react';
import {StyleSheet, Text} from 'react-native';

export const HomeHooks = () => {
  return <Text style={styles.paragraph}>Hello from HomeHooks</Text>;
};

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

touch ile Home class'ını  tanımlamak için Class dizininde index.js adında bir dosya oluşturun
$ touch src/screens/Home/Class/index.js

index.js dosyasının içeriğini aşağıdaki şekilde güncelleyin.
import React, {Component} from 'react';
import {StyleSheet, Text} from 'react-native';

export default class Home extends Component {
  render() {
    return <Text style={styles.paragraph}>Hello from Home</Text>;
  }
}

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

touch ile src dizininde bir wrapper component oluşturun. Bu componentin içinde diğer componentleri load edeceğiz.
$ touch src/wrapper/index.js

index.js dosyasının içeriğini aşağıdaki şekilde güncelleyin.
import React, {Component} from 'react';
import {SafeAreaView, StyleSheet} from 'react-native';
import Home from 'appScreen/Home/Class';
import {HomeHooks} from 'appScreen/Home/Hooks';

export default class Wrapper extends Component {
  render() {
    return (
      <SafeAreaView style={styles.container}>
        <Home />
        <HomeHooks />
      </SafeAreaView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});


Dikkat edilmesi gereken birkaç nokta:

  • Class olarak component tanımlaması yapılırsa bu class React.Componenti extend etmelidir. Hooks yapısında fonksiyon olarak tanımlandığı için extend yoktur.
  • Class olarak tanımlanan componentin render methodu olmalıdır. Hooks yapısında direk değer return edilmelidir.
  • src/screens/Home/Class/index.js dosyasında Class export edilerek ve React.Component'i extend ederek bir component oluşturuldu.
  • src/screens/Home/Hooks/index.js dosyasında ise fuction export edilerek bir component oluşturuldu.
  • Wrapper component içine import ederken Hooks ile oluşturulan component method tabanlı olması nedeniyle  direkt kullanım için süslü parantezler kullanılarak import edildi.  
  • Style tanımlama da dahil olmak üzere diğer kullanımların tamamı aynı şekildedir.

github: https://github.com/lvntyldz/tutorials/tree/1-react-hooks-hw/react-native-hooks-examples



28 Temmuz 2018 Cumartesi

React Context API Kullanımı

Herkese merhaba,
bu yazımda sizlere React Context  API kullanımından bahsedeceğim.  React ile geliştirme yapıyorsanız komponentler arasında parametre taşıma ve değişiklikleri üst/alt komponentlere taşımanın ne kadar kompleks bir durum olduğunu farketmişsinizdir.  Bu durumu aşabilmek için herkes gibi ben de Redux kullanıyordum ve session da tutulması gereken obje/değişkenleri Redux'a atarak ilerliyordum. Global object olarak redux aracılığıyla alt yada üst komponentlere session değerlerini  taşıyordum.

Ancak Redux'ın implementasyonu, ilgili komponentlerle ilişkilendirilmesi, Action ve Action Type ların oluşturulması,..vs açıkçası biraz yorucu olmaktaydı. Çünkü büyük ve kompleks projelerde tree yapısındaki komponentlere hükmetmek pek kolay olmuyordu. Daha ergonomik bir çözüm arayan react geliştiricileri  son dönemde Facebook'un kendisinin bu işe el atarak Context API'yı yayınlamasıyla bir hayli sevindi.

React Context API; sizin komponentler arasında taşımak istediğiniz objeleri bir Provider komponenti oluşturup  bu Provider komponentinin state'inde  tutar.  Alt komponentlerden de yine ContextAPI içinde bulunan  Consumer aracılığıyla erişim imkanı sunar. Sunulan bu yapı sayesinde herhangi bir 3rd entegrasyon yapmadan  komponentleri ortak değişkenlerle ilişkilendirebilirsiniz. Bu ilişkilendirmeyi yaparken Redux ta olduğu gibi Action, ActionType, Container, Reducer tanımlaması yapmanıza da gerek kalmayacaktır.

Sizleri çok fazla yazıya boğmadan şunu belirtmek isterim ki;  buradaki github linkinde Context API kullanımını inceleyip örneklendirdiğim bir proje bulunmaktadır. Bu projeyi inceleyerek Context API ın kullanımını görebilirsiniz.

NOT:  Context API react'ın 16.3 sürümünden sonra eklenmiştir. Belirtilenden daha düşük sürümlerde Context API çalışmayacaktır.

23 Ekim 2017 Pazartesi

Gerçek Android cihaz üzerinde uygulama çalıştırma (React Native)

Merhaba, bu yazımda sizlere mobil geliştirme yaparken emulator yerine gerçek cihaz üzerinde nasıl çalışılacağını paylaşacağım.  Aslında arada hiç bir fark yok normal şartlarda zaten emulator gerçek bir andorid cihazın davranışlarını sergilemeye çalışmaktadır.  Dolayısıyla cihazınızı  USB  ile bilgisayarınıza bağlayıp react-native run-android dediğinizde otomatik olarak uygulamanız cihaza gönderilecektir.  Biraz daha detaylı bilgi için terminali açın ve aşağıdaki adımları takip edin.

Bilgisayarınıza bağlı android  cihazları ve emulatorleri görüntüleyin
adb devices 

aşağıdaki şekilde bir çıktı almalısınız.
(ooddkkffrrffgggdd device)

Eğer USB ile bağladığınız mobil cihazı göremediyseniz. adb'yi yeniden başlatın. 
 adb kill-server && adb devices

uygulamayı  çalıştırın(bu komutla uygulama android cihazda çalışacaktır) 
 react-native run-android


NOT : android 5.1 den düşük bir sürümdeyse cihazınız mobil cihaz bilgisayarınızdaki server'a ağ yoluyla ulaşacaktır. Mobil cihaz ve bilgisayarın aynı ağda(networkte) olduğundan emin olun.

mobil cihazda uygulama çalışırken aşağıdaki komutu göndererek developer menüsünü açın 
adb shell input keyevent 82 


NOT : Eğer bu komutu uygulama çalışmadan(launcher ekranındayken) yollarsanız. Settings menüsü açılır. Bizim istediğimiz ise developer settings menüsüdür.
Dolayısıyla mobil cihaz sizin geliştirdiğiniz uygulama ekranındayken bu komutu bilgisayarınızdan çalıştırın.

"dev settings" -> "Debug server host & port for devices"  kısmına tıklayın
açılan ekrandan bilgisayarın IP adresini ve server'in portunu girin
(ÖRN : 10.1.1.145:8081)

Geriye dönerek uygulamayı yeniden yükle(reload) linkine basın.

Bu işlemden sonra  cihazdaki uygulamanız 10.1.1.145:8081 üzerinden iletişim kurarak çalışacaktır.