React Hooks: Modern React Geliştirmenin Temelleri

React Hooks'ların nasıl çalıştığını, en yaygın kullanım senaryolarını ve best practice'leri öğrenin. useState, useEffect, useContext ve custom hooks örnekleriyle birlikte.

5 min read
Paylaş:

React Hooks: Modern React Geliştirmenin Temelleri

React Hooks, React 16.8 ile gelen ve fonksiyonel bileşenlerde state yönetimi ve side effect'leri kolaylaştıran özelliklerdir. Bu yazıda, en yaygın kullanılan hooks'ları ve best practice'leri inceleyeceğiz.

Hooks Nedir?

Hooks, fonksiyonel bileşenlerde state ve diğer React özelliklerini kullanmanızı sağlayan özel fonksiyonlardır. Class component'lerin karmaşıklığını ortadan kaldırır ve kodun daha okunabilir olmasını sağlar.

Temel Hooks

1. useState

useState hook'u, fonksiyonel bileşenlerde state yönetimi için kullanılır:

import React, { useState } from 'react';
 
function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Sayı: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Artır
      </button>
    </div>
  );
}

2. useEffect

useEffect hook'u, side effect'leri yönetmek için kullanılır:

import React, { useState, useEffect } from 'react';
 
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    async function fetchUser() {
      try {
        const response = await fetch(`/api/users/${userId}`);
        const userData = await response.json();
        setUser(userData);
      } catch (error) {
        console.error('Kullanıcı yüklenemedi:', error);
      } finally {
        setLoading(false);
      }
    }
    
    fetchUser();
  }, [userId]); // userId değiştiğinde effect tekrar çalışır
  
  if (loading) return <div>Yükleniyor...</div>;
  if (!user) return <div>Kullanıcı bulunamadı</div>;
  
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

İleri Seviye Hooks

3. useContext

useContext hook'u, prop drilling'i önlemek için global state yönetimi sağlar:

// ThemeContext.js
import React, { createContext, useContext, useState } from 'react';
 
const ThemeContext = createContext();
 
export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}
 
export function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }
  return context;
}
 
// App.js
function App() {
  return (
    <ThemeProvider>
      <Header />
      <Main />
    </ThemeProvider>
  );
}
 
// Header.js
function Header() {
  const { theme, setTheme } = useTheme();
  
  return (
    <header className={theme}>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Tema Değiştir
      </button>
    </header>
  );
}

4. useReducer

Karmaşık state yönetimi için useReducer kullanılır:

import React, { useReducer } from 'react';
 
const initialState = {
  count: 0,
  history: []
};
 
function reducer(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return {
        ...state,
        count: state.count + 1,
        history: [...state.history, state.count]
      };
    case 'DECREMENT':
      return {
        ...state,
        count: state.count - 1,
        history: [...state.history, state.count]
      };
    case 'RESET':
      return initialState;
    default:
      return state;
  }
}
 
function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  
  return (
    <div>
      <p>Sayı: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>
        Artır
      </button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>
        Azalt
      </button>
      <button onClick={() => dispatch({ type: 'RESET' })}>
        Sıfırla
      </button>
      <div>
        <h4>Geçmiş:</h4>
        <ul>
          {state.history.map((value, index) => (
            <li key={index}>{value}</li>
          ))}
        </ul>
      </div>
    </div>
  );
}

Custom Hooks

Kendi hook'larınızı oluşturarak kod tekrarını önleyebilirsiniz:

// useLocalStorage.js
import { useState, useEffect } from 'react';
 
function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });
  
  const setValue = (value) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.error(error);
    }
  };
  
  return [storedValue, setValue];
}
 
// Kullanım
function App() {
  const [name, setName] = useLocalStorage('name', '');
  
  return (
    <div>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Adınızı girin"
      />
    </div>
  );
}

Best Practices

1. Hook Kuralları

  • Hooks'ları sadece React fonksiyonlarında kullanın
  • Hooks'ları sadece en üst seviyede çağırın
  • Hooks'ları sadece React fonksiyonlarında çağırın

2. useEffect Dependency Array

// ❌ Yanlış - sonsuz döngü
useEffect(() => {
  fetchData();
});
 
// ✅ Doğru - sadece component mount olduğunda
useEffect(() => {
  fetchData();
}, []);
 
// ✅ Doğru - dependency değiştiğinde
useEffect(() => {
  fetchData();
}, [userId]);

3. Custom Hook Naming

Custom hook'larınızı use ile başlatın:

// ✅ Doğru
function useCounter() { ... }
function useLocalStorage() { ... }
function useApi() { ... }
 
// ❌ Yanlış
function counter() { ... }
function localStorage() { ... }

Performans Optimizasyonu

useMemo ve useCallback

import React, { useMemo, useCallback } from 'react';
 
function ExpensiveComponent({ items, filter }) {
  // Pahalı hesaplama
  const filteredItems = useMemo(() => {
    return items.filter(item => item.includes(filter));
  }, [items, filter]);
  
  // Callback fonksiyonu
  const handleClick = useCallback((id) => {
    console.log('Item clicked:', id);
  }, []);
  
  return (
    <div>
      {filteredItems.map(item => (
        <button key={item} onClick={() => handleClick(item)}>
          {item}
        </button>
      ))}
    </div>
  );
}

Sonuç

React Hooks, modern React geliştirmenin temelidir. Doğru kullanıldığında:

  • ✅ Daha temiz ve okunabilir kod
  • ✅ Daha az boilerplate
  • ✅ Daha iyi performans
  • ✅ Daha kolay test edilebilirlik

sağlar. Hooks'ları öğrenmek ve doğru kullanmak, React geliştiricisi olarak kariyerinizde büyük fark yaratacaktır.

Kaynaklar


Bu yazı React Hooks konusunda size rehberlik etmeyi amaçlamaktadır. Sorularınız için yorum bırakabilirsiniz!