React Hooks’a Kısa Bir Giriş

Selamlar. Bu yazıda React Hooks'a Kısa Bir Giriş yapacağız. Araştırdğım kadarıyla React Hooks hakkında araştırmalarımı size aktaracağım. Öncelikle belirteyim, projelerimde React hiç kullanmadım diyebiliriz. Yani state'i sonuna kadar kullanacağım hatta bana yetersiz geldiği için dış alternatiflere yöneleceğim durumları yaşamadım.

Ancak bir süredir React Hooks üzerine yapılan yorumlar, yazılan blog yazıları azıcık araştırmam konusunda bir hayli ikna edici oldu.

Heartsmagic ile bu konuda da baya konuşmuştuk. Bir süre karmaşa yaşamıştım.

React Hooks Ne iş Yapar?

React Hooks class componentlerde kullandığımız state özelliğini fonksiyon componentlerde kullanmamıza izin veriyor. Yani react hooks gelene kadar direkt fonksiyonel componentler üzerinde dahili state mekanizmasını kullanamıyordunuz.

React Hooks Nasıl Kullanılır?

React projesini oluşturduk diyelim. Bunu yapmadan zaten olmuyor :/) Neyse import ifademize bir de useState ekleyeceğiz. Şöyle olacak;

import React, { useState } from 'react';

Bu sadece başlangıç için. Şimdi normalde class component ile default olarak oluşturulan projenin App class'ini şöyle değiştirelim;

function App() {

  const [sayi, setSayi] = useState(0)

  function arttir() {
    setSayi(sayi + 1)
  }

  function azalt() {
    setSayi(sayi - 1)
  }

  return (
    <React.Fragment>
      <button onClick={arttir}>+1</button>
      <button onClick={azalt}>-1</button>

      <p>{sayi}</p>
    </React.Fragment>
  );
}

Ben React.Fragment kullandım çünkü render işleminde mutlaka bir adet top element olmalı. Fonksiyon içerisine baktığımızda const ile tanımlanan bir ifade görüyoruz.

Bu kısımda gelen ilk değişken state'i taşıyan değişken oluyor. Daha sonra setSayi ise state'i değiştirebileceğimiz fonksiyon olacak. Burada siz istediğiniz ismi verebiliyorsunuz en güzel yanı da bu. Son olarak useState(0) ile initial bir state atamasını gerçekleştirdik. Burada initial state herhangi bir değer alabilir. Başlangıçta 0 olabilir ya da true olabilir ya da object olabilir. Örnek tanımlama şekilleri şöyle;

useState(0)
useState(null)
useState({})
useState(true)

Kısacası her türden veriyi geçirebilirsiniz. Eğer bunu bir class component ile yapmak isteseydik şöyle yazacaktık;

class App extends Component {
    state = {
        sayi: 0
    }
}

State'in Update Olduğu Durum

React Hooks state'in update olduğu durumlar için useEffect isimli bir fonksiyonu bize sunuyor. Import ifademiz şöyle değişecek;

import React, { useState, useEffect } from 'react';

Kullanacağımız useEffect fonksiyonu componentDidMount, componentDidUpdate ve componentWillUnmount fonksiyonları ile aynı şekilde çalışır. Yaptığımız örnekte fonksiyonumuz hem component ilk açıldığında hem de state değeri değiştiği anda bize bir mesaj verecek;

import React, { useState, useEffect } from 'react';

function App() {

  const [sayi, setSayi] = useState(0)

  function arttir() {
    setSayi(sayi + 1)
  }

  function azalt() {
    setSayi(sayi - 1)
  }

  useEffect(() => {
    console.log('State değeri:', sayi)
  })

  return (
    <React.Fragment>
      <button onClick={arttir}>+1</button>
      <button onClick={azalt}>-1</button>

      <p>{sayi}</p>
    </React.Fragment>
  );
}

Bu örnek kodu çalıştırdığınız zaman tarayıcı konsolunu açın. Sayfayı her refresh ettiğinizde initial value yani state'in ilk değeri yazılacaktır. Ardından state'e uyguladığımız arttır ve azalt işlemleri için de tekrar tekrar bu işlem gerçekleşecek.

Diyelim ki componentWillUnmount ile yaptığınız bir şey vardı ve onu burada da kullanmak istiyorsunuz. Bunun için useEffect'e bir fonksiyon return ettirmelisiniz. Örnek olarak useEffect'i şöyle değiştirelim;

useEffect(() => {
    console.log('State değeri:', sayi)

    return () => console.log('componentWillUnmount Çalıştı');
})

Dilerseniz sayi değişkenini willUnmount kısmında yazdırın. State'in bir önceki değerini alacaksınız. Şimdi bir problem daha var. Mesela 2 tane şöyle state tanımladınız diyelim;

const [sayi, setSayi] = useState(0)
const [sayi1, setSayi1] = useState(0)

Normalde böyle olmaz ama diyelim ki böyle ve siz sadece sayi değiştiğinde useEffect kullanmak istiyorsunuz. Bunun için useEffect'in ikinci parametresine değişken adını şöyle ekleyin;

useEffect(() => {
    console.log('State değeri:', sayi)

    return () => console.log('componentWillUnmount Çalıştı');
}, [sayi])

Anladığınız üzere 2. argüman array türünden veri almış yani birden fazla state'e bağlı olarak çalışmasını sağlayabilirsiniz. O zaman örneğimiz genel olarak şöyle kodlanır;

function App() {

  const [sayi, setSayi] = useState(0)
  const [sayi1, setSayi1] = useState(0)

  function arttir() {
    setSayi(sayi + 1)
    setSayi1(sayi1 + (sayi + 2))
  }

  function azalt() {
    setSayi(sayi - 1)
    setSayi1(sayi1 - (sayi + 2))
  }

  useEffect(() => {
    console.log('Sayi:', sayi, 'Sayi1:', sayi1)

    return () => console.log('componentWillUnmount Çalıştı');
  }, [sayi, sayi1])

  return (
    <React.Fragment>
      <button onClick={arttir}>+1</button>
      <button onClick={azalt}>-1</button>

      <p>Sayi: {sayi} - Sayi1: {sayi1}</p>
    </React.Fragment>
  );
}

Bu tekil ile 2 hooks'un çalıştığını görebilirsiniz. Peki 2 adet state'in farklı effectler ile kontrolü nasıl sağlanır? İlk state'i oluşturduğumuz satırın altına useEffect fonksiyonunu yazarsak bir üstteki state'i kontrol etmiş oluruz. Örnek şöyle;

const [sayi, setSayi] = useState(0)

  useEffect(() => {
    console.log('Sayi', sayi)

    return () => console.log('componentWillUnmount Çalıştı');
  })

  const [sayi1, setSayi1] = useState(0)

  useEffect(() => {
    console.log('Sayi1', sayi1)

    return () => console.log('componentWillUnmount Çalıştı');
  })

Şimdilik bu ufak girişte bunları size sunabildim. Belki serinin devamını getirebilirim. Gelecek yazılarda useEffect, useRef vs. gibi fonksiyonlara bakabiliriz. Bu yazıda React Hooks'a Kısa Bir Giriş yaptık.

Özetlersek

React Hooks ile birlikte fonksiyonel componentlerde state yönetimi bir hayli kolay hale gelmiş durumda.

Önceden var olan stateless ve stateful component kavramını tekrar gözden geçirmek gerekecek gibi.

useEffect fonksiyonunu doğru bir şekilde kullanırsak her render işleminde çalışmasını engelleyebiliriz.

useEffect fonksiyonunu birden fazla kullanacaksak ki bu 2. bir state daha varsa mantıklı o zaman hedef state'in alt satırına eklememiz daha doğru olacaktır.

Kaynaklar

Bu yazı hazırlanırken aşağıdaki kaynaklar bana yardımcı oldu;