React Hooks: Modern React Geliştirme Rehberi
React Hooks kullanarak daha temiz, daha okunabilir ve daha güçlü React uygulamaları geliştirmeyi öğrenin.

React Hooks: Modern React Geliştirme Rehberi
React Hooks, React 16.8 ile tanıtılan ve React geliştirmede devrim yaratan bir özelliktir. Bu rehberde, Hooks'un tüm yönlerini inceleyecek ve modern React uygulamaları geliştirme becerilerinizi geliştireceksiniz.
React Hooks Nedir?
Hooks, fonksiyonel komponentlerde state ve diğer React özelliklerini kullanmanızı sağlayan fonksiyonlardır. Class component'lere ihtiyaç duymadan React'ın tüm gücünü kullanabilirsiniz.
Hooks'un Avantajları
- Daha Az Kod: Class syntax'ına gerek yok
- Daha İyi Kod Organizasyonu: İlgili mantığı birlikte tutma
- Kolay Test Edilebilirlik: Pure functions daha kolay test edilir
- Kod Yeniden Kullanımı: Custom Hooks ile mantık paylaşımı
useState: State Yönetimi
En temel Hook olan useState, komponentlerde state tutmayı sağlar.
Temel Kullanım
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Sayaç: {count}</p>
<button onClick={() => setCount(count + 1)}>
Artır
</button>
</div>
);
}
Nesne ve Dizi State'i
function UserProfile() {
const [user, setUser] = useState({
name: '',
email: '',
age: 0
});
const updateName = (name) => {
setUser(prev => ({
...prev,
name: name
}));
};
return (
<input
value={user.name}
onChange={(e) => updateName(e.target.value)}
/>
);
}
Lazy Initial State
Pahalı hesaplamalar için lazy initialization:
function ExpensiveComponent() {
// Bu fonksiyon sadece ilk render'da çalışır
const [data, setData] = useState(() => {
const initialData = computeExpensiveValue();
return initialData;
});
}
useEffect: Yan Etki Yönetimi
useEffect, component lifecycle'ını yönetmek için kullanılır.
Temel Kullanım
import { useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
// API çağrısı
fetch('https://api.example.com/data')
.then(res => res.json())
.then(data => setData(data));
}, []); // Boş dependency array = sadece mount'ta çalış
return <div>{data && JSON.stringify(data)}</div>;
}
Cleanup Fonksiyonu
function WebSocketComponent() {
useEffect(() => {
const ws = new WebSocket('ws://localhost:8080');
ws.onmessage = (event) => {
console.log('Mesaj alındı:', event.data);
};
// Cleanup: component unmount olduğunda
return () => {
ws.close();
};
}, []);
}
Dependency Array Best Practices
function SearchComponent() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
useEffect(() => {
if (!query) return;
const timer = setTimeout(() => {
searchAPI(query).then(setResults);
}, 500); // Debouncing
return () => clearTimeout(timer);
}, [query]); // query değiştiğinde çalış
}
useContext: Context API Kullanımı
Global state yönetimi için useContext:
import { createContext, useContext, useState } from 'react';
// Context oluştur
const ThemeContext = createContext();
// Provider component
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
// Consumer component
function ThemedButton() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
className={theme}
>
Tema: {theme}
</button>
);
}
useReducer: Kompleks State Yönetimi
useState'e alternatif olarak, karmaşık state mantığı için:
import { useReducer } from 'react';
const initialState = { count: 0, step: 1 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { ...state, count: state.count + state.step };
case 'decrement':
return { ...state, count: state.count - state.step };
case 'setStep':
return { ...state, step: action.payload };
case 'reset':
return initialState;
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Sayaç: {state.count}</p>
<input
value={state.step}
onChange={(e) => dispatch({
type: 'setStep',
payload: Number(e.target.value)
})}
/>
<button onClick={() => dispatch({ type: 'increment' })}>
+{state.step}
</button>
<button onClick={() => dispatch({ type: 'decrement' })}>
-{state.step}
</button>
<button onClick={() => dispatch({ type: 'reset' })}>
Sıfırla
</button>
</div>
);
}
useRef: DOM Referansları ve Mutable Values
DOM Referansı
import { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// Component mount olunca input'a focus
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
Mutable Value Storage
function Timer() {
const [seconds, setSeconds] = useState(0);
const intervalRef = useRef(null);
const startTimer = () => {
intervalRef.current = setInterval(() => {
setSeconds(s => s + 1);
}, 1000);
};
const stopTimer = () => {
clearInterval(intervalRef.current);
};
return (
<div>
<p>Geçen süre: {seconds}s</p>
<button onClick={startTimer}>Başlat</button>
<button onClick={stopTimer}>Durdur</button>
</div>
);
}
useMemo ve useCallback: Performance Optimization
useMemo: Expensive Calculations
import { useMemo, useState } from 'react';
function ExpensiveComponent({ items }) {
const [filter, setFilter] = useState('');
// Sadece items veya filter değiştiğinde yeniden hesapla
const filteredItems = useMemo(() => {
console.log('Filtering items...');
return items.filter(item =>
item.name.toLowerCase().includes(filter.toLowerCase())
);
}, [items, filter]);
return (
<div>
<input
value={filter}
onChange={e => setFilter(e.target.value)}
/>
<ul>
{filteredItems.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
useCallback: Function Memoization
import { useCallback, memo } from 'react';
// Memo ile optimize edilmiş child component
const Button = memo(({ onClick, children }) => {
console.log('Button rendered:', children);
return <button onClick={onClick}>{children}</button>;
});
function Parent() {
const [count, setCount] = useState(0);
const [other, setOther] = useState(0);
// useCallback olmadan, her render'da yeni fonksiyon
// useCallback ile, sadece count değişince yeni fonksiyon
const increment = useCallback(() => {
setCount(c => c + 1);
}, []);
return (
<div>
<p>Count: {count}</p>
<p>Other: {other}</p>
<Button onClick={increment}>Artır Count</Button>
<button onClick={() => setOther(o => o + 1)}>
Artır Other
</button>
</div>
);
}
Custom Hooks: Kendi Hook'larınızı Oluşturun
useFetch Hook
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
setLoading(true);
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(err => {
setError(err);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}
// Kullanım
function UserProfile({ userId }) {
const { data, loading, error } = useFetch(`/api/users/${userId}`);
if (loading) return <div>Yükleniyor...</div>;
if (error) return <div>Hata: {error.message}</div>;
return <div>{data.name}</div>;
}
useLocalStorage Hook
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.log(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.log(error);
}
};
return [storedValue, setValue];
}
// Kullanım
function App() {
const [name, setName] = useLocalStorage('name', '');
return (
<input
value={name}
onChange={e => setName(e.target.value)}
/>
);
}
React Hooks Best Practices
1. Hook Kuralları
// ✅ DOĞRU: En üst seviyede çağır
function Component() {
const [state, setState] = useState(0);
useEffect(() => {}, []);
}
// ❌ YANLIŞ: Koşullu kullanma
function Component() {
if (condition) {
const [state, setState] = useState(0); // HATA!
}
}
2. Dependency Array Doğruluğu
// ✅ DOĞRU: Tüm dependencies belirtilmiş
useEffect(() => {
console.log(value1, value2);
}, [value1, value2]);
// ❌ YANLIŞ: Eksik dependency
useEffect(() => {
console.log(value1, value2);
}, [value1]); // value2 eksik!
3. Custom Hook Naming
// ✅ DOĞRU: "use" prefix ile başla
function useCustomHook() {}
// ❌ YANLIŞ: "use" prefix olmadan
function customHook() {} // React bunu Hook olarak tanımaz
Real-World Örnek: Shopping Cart
function useShoppingCart() {
const [cart, setCart] = useState([]);
const addItem = useCallback((product) => {
setCart(prev => {
const existing = prev.find(item => item.id === product.id);
if (existing) {
return prev.map(item =>
item.id === product.id
? { ...item, quantity: item.quantity + 1 }
: item
);
}
return [...prev, { ...product, quantity: 1 }];
});
}, []);
const removeItem = useCallback((productId) => {
setCart(prev => prev.filter(item => item.id !== productId));
}, []);
const total = useMemo(() => {
return cart.reduce((sum, item) =>
sum + (item.price * item.quantity), 0
);
}, [cart]);
return { cart, addItem, removeItem, total };
}
function ShoppingCart() {
const { cart, addItem, removeItem, total } = useShoppingCart();
return (
<div>
<h2>Sepetim</h2>
{cart.map(item => (
<div key={item.id}>
<span>{item.name} x {item.quantity}</span>
<button onClick={() => removeItem(item.id)}>Sil</button>
</div>
))}
<p>Toplam: {total} TL</p>
</div>
);
}
Sonuç
React Hooks, modern React geliştirmede vazgeçilmez bir araçtır. CodeBros olarak projelerimizde:
- ✅ Hooks-first yaklaşımı benimsiyoruz
- ✅ Custom Hooks ile kod tekrarını önlüyoruz
- ✅ Performance optimization için useMemo/useCallback kullanıyoruz
- ✅ Clean ve maintainable kod yazıyoruz
React projelerinizde profesyonel destek için CodeBros ekibi ile iletişime geçin!
Etiketler: #React #Hooks #JavaScript #Frontend #WebDevelopment #ReactJS #CodeBros



