5 Mayıs 2020 Salı

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

Hiç yorum yok:

Yorum Gönder