React Hooks

Esra Nur Mülkpınar
Bursa Bilişim Topluluğu
6 min readJun 7, 2024

Merhaba sevgili geliştirici dostlarım, kahveler hazırsa bizde hazırırız.🚀 Bugün konumuz React 16.8 sürümüyle hayatımıza giren React Hooks. İyi okumalar diliyorum 👩🏻‍💻

Bu yazıdaki konu başlıkları:

  1. Hooks Nedir?
  2. Neden Hooks Kullanırız?
  3. useState Hook’u
  4. useEffect Hook’u
  5. useContext Hook’u
  6. useDispatch Hook’u
  7. useSelector Hook’u
  8. useReducer Hook’u
  9. useCallback Hook’u
  10. useMemo Hook’u
  11. Custom Hooks
  12. Hook Kullanırken Dikkat Etmeniz Gerekenler

Hooks Nedir?

React Hooks, state ve side effect yönetimi için kullanılan özel fonksiyonlardır. Ayrıca kendi Hook’larınızı oluşturmak için de kullanabilirsiniz. React componentlerinde class bileşenlere ihtiyaç duymadan state ve diğer React özelliklerini kullanmamıza olanak tanır.

Neden Hooks Kullanırız?

Hooks, React’in esnekliğini ve gücünü artırarak, daha okunabilir, yeniden kullanılabilir ve sürdürülebilir kod yazmanıza olanak tanır. Hooks kullanımıyla birlikte, fonksiyonel bileşenlerde state yönetimi ve yaşam döngüsü metodlarını kullanabiliriz.

useState Hook’u

useState, React’te state yönetimi için kullanılan en temel Hook’tur. Bir componentin state’ini tanımlar ve bu state’i güncellemek için bir fonksiyon döner.

Kullanım Örneği:

import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

Bu örnekte, useState Hook'u ile count adında bir state değişkeni ve setCount adında bu state'i güncelleyen bir fonksiyon tanımlanır. Butona her tıklandığında, setCount fonksiyonu kullanılarak count değeri bir artırılır.

useEffect Hook’u

useEffect, side effect’leri yönetmek için kullanılır. Bu, componentlerin mount, update ve unmount aşamalarında belirli kod parçalarını çalıştırmamıza olanak tanır.

Mount: Bir componentin DOM’a ilk kez eklenmesidir. Bu aşamada, componentin başlangıç state’i ayarlanır ve ilk render gerçekleşir.

Update: Componentin props veya state değişikliklerine bağlı olarak yeniden render edilmesidir. Bu aşamada, component güncellenmiş verilerle tekrar render edilir.

Unmount: Bir componentin DOM’dan kaldırılmasıdır. Bu aşamada, componentle ilgili temizleme işlemleri yapılır.

Kullanım Örneği:

import React, { useEffect, useState } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(seconds => seconds + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <div>{seconds} seconds have passed.</div>;
}

Bu örnekte, useEffect Hook'u ile bir zamanlayıcı oluşturulur. Component ilk defa render edildiğinde (mount) bir setInterval fonksiyonu çalıştırılır ve her saniye seconds değeri bir artırılır. Component unmount edildiğinde ise clearInterval ile zamanlayıcı temizlenir.

useContext Hook’u

useContext, React’in context API’sini kullanarak, componentler arasında veri paylaşımını sağlar.

Kullanım Örneği:

import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme === 'dark' ? '#333' : '#FFF' }}>
I am styled by theme context!
</button>
);
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}

Bu örnekte, useContext Hook'u ile ThemeContext içerisindeki tema bilgisi alınır ve butonun arka plan rengi buna göre ayarlanır.

✨ useDispatch Hook’u

useDispatch, Redux store'daki eylemleri dispatch etmek (göndermek) için kullanılır. Eylemler (actions), store’daki state’i güncelleyen işlemlerdir.

Redux, JavaScript uygulamaları için merkezi bir state yönetim kütüphanesidir ve genellikle React ile birlikte kullanılır. Uygulamanın tüm state’ini tek bir store’da tutarak, state yönetimini daha öngörülebilir ve yönetilebilir hale getirir.

Kullanım Örneği:

import React from 'react';
import { useDispatch } from 'react-redux';
import { increment } from './counterSlice';
function Counter() {
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(increment())}>Increment</button>
</div>
);
}

Bu örnekte, useDispatch Hook'u kullanılarak increment aksiyonu dispatch ediliyor. Butona tıklandığında, increment aksiyonu Redux store'a gönderilir ve state güncellenir.

✨ useSelector Hook’u

useSelector, Redux store'daki state'i seçmek ve component içinde kullanmak için kullanılır. Bu Hook, componentlerin gerekli olan state verilerini almasını sağlar.

Kullanım Örneği:

import React from 'react';
import { useSelector } from 'react-redux';
function Counter() {
const count = useSelector((state) => state.counter.value);
return (
<div>
<p>Count: {count}</p>
</div>
);
}

Bu örnekte, useSelector Hook'u kullanılarak Redux store'daki counter slice'ındaki value state'i seçiliyor. Seçilen count değeri component içinde gösteriliyor.

useReducer Hook’u

useReducer, daha karmaşık state mantığı ve state geçişleri için kullanılır. Redux benzeri bir state yönetimi sağlar.

Kullanım Örneği:

import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}

Bu örnekte, useReducer Hook'u ile bir sayaç uygulaması oluşturulmuştur. reducer fonksiyonu, state geçişlerini yönetir ve dispatch fonksiyonu ile bu geçişler tetiklenir.

useCallback Hook’u

useCallback, bir fonksiyonun yeniden oluşturulmasını önleyerek performans iyileştirmesi sağlar. Özellikle gereksiz render’ları önlemek için kullanılır.

Kullanım Örneği:

import React, { useState, useCallback } from 'react';
function ExpensiveComponent({ calculate }) {
console.log('Rendering expensive component');
return <div>{calculate()}</div>;
}
function App() {
const [count, setCount] = useState(0);
const calculate = useCallback(() => {
return count * 2;
}, [count]);
return (
<div>
<ExpensiveComponent calculate={calculate} />
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

Bu örnekte, useCallback Hook'u ile calculate fonksiyonu memorized edilir ve sadece count değiştiğinde yeniden oluşturulur. Bu sayede ExpensiveComponent gereksiz yere render edilmez.

Memorized, bir fonksiyonun daha önce hesaplanan sonuçlarını hatırlayarak performansı artıran bir optimizasyon tekniğidir. Bu, aynı girdilerle tekrar çağrıldığında hesaplamayı yeniden yapmadan önceki sonucu kullanmasını sağlar.

useMemo Hook’u

useMemo, bir değeri memorized ederek, sadece bağımlılıkları değiştiğinde yeniden hesaplanmasını sağlar. Performans iyileştirmesi için kullanılır.

Kullanım Örneği:

import React, { useMemo, useState } from 'react';
function ExpensiveCalculationComponent() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');

const expensiveCalculation = useMemo(() => {
console.log('Calculating...');
return count * 2;
}, [count]);

return (
<div>
<p>Result of expensive calculation: {expensiveCalculation}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="Type something..."
/>
</div>
);
}
export default ExpensiveCalculationComponent;

Bu örnekte, useMemo Hook'u expensiveCalculation sonucunu hafızaya alır ve sadece count değiştiğinde yeniden hesaplar. inputValue değiştiğinde hesaplama tekrar yapılmaz, böylece gereksiz hesaplamalar önlenir ve performans artırılır.

Custom Hooks

Custom Hooks, uygulamanıza özel mantığı kapsülleyip tekrar kullanılabilir hale getirmenizi sağlar. Bu, kodunuzu daha modüler ve temiz hale getirir.

Kullanım Örneği:

import { useState, useEffect } from 'react';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
function App() {
const width = useWindowWidth();
return <div>Window width: {width}</div>;
}

Bu örnekte, useWindowWidth adında bir custom Hook oluşturulmuştur. Bu Hook, pencere genişliğini takip eder ve App componentinde kullanılır.

✨ Hook Kullanırken Dikkat Etmeniz Gerekenler

React hook’larını kullanırken ve kendi hook’larınızı yazarken dikkat etmeniz gereken bazı kurallar ve en iyi uygulamalar vardır. İşte bazı önemli noktalar:

🚀 Custom Hook

1. “use” ile Başlamalıdır

Kendi hook’unuzu yazarken ismi use ile başlamalıdır. Bu, React'e bunun bir hook olduğunu ve hook kurallarının geçerli olduğunu bildirir.

2. Sadece Fonksiyon İçinde Kullanılmalıdır

Hook’lar sadece fonksiyon componentlerin veya diğer hook’ların içinde kullanılmalıdır.

3. React Kurallarına Uymalıdır

Hook’ları sadece en üst seviyede çağırmalısınız, koşullar veya döngüler içinde çağırmamalısınız. Bu, React’in hook’ların çağrı sırasını takip edebilmesini sağlar.

4. Diğer Hook’ları Kullanabilir

Kendi hook’unuz içinde diğer hook’ları (useState, useEffect, vb.) kullanabilirsiniz. Bu, hook'ların gücünü ve esnekliğini artırır.

🚀 Performans Optimizasyonu

1. Bağımlılık Listeleri

Hook’lar, özellikle useEffect, useCallback, ve useMemo gibi hook'lar, bağımlılık listeleri kullanarak belirli değişkenlere bağlı kalırlar. Her zaman bağımlılık listesini doğru şekilde belirtmelisiniz.

2. Memoization Kullanımı

Pahalı hesaplamaları veya fonksiyonları yeniden hesaplamaktan kaçınmak için useMemo ve useCallback hook'larını kullanabilirsiniz.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);

🚀 Custom Hook’larda State ve Effect Kullanımı

Custom hook’lar, state ve yan etkileri yönetmek için useState ve useEffect gibi yerleşik hook'ları kullanabilir. Bu, custom hook'ların componentlerin karmaşıklığını azaltmasına yardımcı olur.

🚀 Reusability and Abstraction

Custom hook’lar, belirli bir mantığı veya işlemi tekrar kullanılabilir ve soyut bir şekilde paketlemeyi sağlar. Bu, kodunuzu daha temiz ve yönetilebilir hale getirir.

🚀 Error Handling ve Debugging

1. Hataları Yönetme

Custom hook’larınızın hataları düzgün bir şekilde ele aldığından emin olun. Try-catch blokları ve hata durumlarını yöneten state değişkenleri kullanabilirsiniz.

2. Debugging

React DevTools kullanarak hook’larınızı debug edebilirsiniz. Custom hook’ların state ve effect’lerini takip etmek için React DevTools’un sağladığı özelliklerden faydalanabilirsiniz.

🚀 Örnek Kullanımlar

1. Form Handling Custom Hook

Form işleme için custom hook oluşturabilirsiniz.

import { useState } from 'react';
function useForm(initialValues) {
const [values, setValues] = useState(initialValues);
const handleChange = (event) => {
const { name, value } = event.target;
setValues({
...values,
[name]: value,
});
};
return [values, handleChange];
}
export default useForm;

2. Fetching Data Custom Hook

Veri çekme işlemleri için custom hook oluşturabilirsiniz.

import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;

Eğer yazıyı beğendiyseniz, diğer içeriklerime göz atmayı unutmayın. Keyifli okumalar! 📚

Bana destek olmak için kahve ısmarlayabilirsiniz 🌟

Benimle iletişime geçmek isterseniz: Esra Nur Mülkpınar

--

--