React Hooks, fonksiyonel bileşenlerde state yönetimini mümkün kılan devrim niteliğinde bir özelliktir. Bu yazıda, en önemli hooks'ları ve nasıl kullanılacaklarını detaylı olarak öğreneceğiz.
Hooks Nedir?
Hooks, React 16.8 ile gelen ve fonksiyonel bileşenlerde state ve diğer React özelliklerini kullanmamızı sağlayan fonksiyonlardır. Class component'lerin karmaşıklığını ortadan kaldırır ve kodun daha okunabilir olmasını sağlar.
useState Hook
useState, fonksiyonel bileşenlerde state tutmamızı sağlar. En temel ve en çok kullanılan hook'tur.
Temel Kullanım
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
Sayı: {count}
);
}
Object State
function UserProfile() {
const [user, setUser] = useState({
name: 'Ahmet',
age: 25,
email: 'ahmet@example.com'
});
const updateName = (newName) => {
setUser(prevUser => ({
...prevUser,
name: newName
}));
};
return (
{user.name}
Yaş: {user.age}
E-posta: {user.email}
);
}
useEffect Hook
useEffect, yan etkileri yönetmemizi sağlar. API çağrıları, DOM manipülasyonu, timer'lar gibi işlemler için kullanılır.
Temel Kullanım
import React, { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Component mount olduğunda çalışır
fetchUsers();
// Cleanup function (component unmount olduğunda çalışır)
return () => {
console.log('Component kaldırıldı');
};
}, []); // Boş dependency array
const fetchUsers = async () => {
try {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
setUsers(data);
setLoading(false);
} catch (error) {
console.error('Hata:', error);
setLoading(false);
}
};
if (loading) return Yükleniyor...;
return (
{users.map(user => (
- {user.name}
))}
);
}
Dependency Array
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
// userId değiştiğinde çalışır
fetchUser(userId);
}, [userId]); // userId dependency olarak eklendi
// ... rest of the component
}
useContext Hook
useContext, prop drilling'i önlemek için global state'i paylaşmamızı sağlar.
Context Oluşturma
// UserContext.js
import React, { createContext, useState } from 'react';
export const UserContext = createContext();
export function UserProvider({ children }) {
const [user, setUser] = useState(null);
const login = (userData) => {
setUser(userData);
};
const logout = () => {
setUser(null);
};
return (
{children}
);
}
Context Kullanımı
// App.js
import { UserProvider } from './UserContext';
function App() {
return (
);
}
// Header.js
import { useContext } from 'react';
import { UserContext } from './UserContext';
function Header() {
const { user, logout } = useContext(UserContext);
return (
{user ? (
Merhaba, {user.name}
) : (
Giriş yapılmadı
)}
);
}
useReducer Hook
useReducer, karmaşık state mantığı için useState'e alternatif olarak kullanılır.
import React, { 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:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
Sayı: {state.count}
Adım: {state.step}
dispatch({
type: 'setStep',
payload: parseInt(e.target.value)
})}
/>
);
}
Custom Hooks
Kendi hooks'larımızı oluşturabiliriz. Bu, kod tekrarını önler ve mantığı yeniden kullanılabilir hale getirir.
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.error('LocalStorage hatası:', error);
return initialValue;
}
});
const setValue = value => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error('LocalStorage kaydetme hatası:', error);
}
};
return [storedValue, setValue];
}
// Kullanımı
function UserSettings() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
const [language, setLanguage] = useLocalStorage('language', 'tr');
return (
);
}
useFetch Hook
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
setData(result);
setError(null);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// Kullanımı
function UserList() {
const { data: users, loading, error } = useFetch('https://api.example.com/users');
if (loading) return Yükleniyor...;
if (error) return Hata: {error};
return (
{users.map(user => (
- {user.name}
))}
);
}
Hooks Kuralları
Hooks kullanırken dikkat edilmesi gereken önemli kurallar vardır:
- Sadece en üst seviyede çağırın: Hooks'ları döngüler, koşullar veya iç fonksiyonlarda çağırmayın
- Sadece React fonksiyonlarında çağırın: Hooks'ları normal JavaScript fonksiyonlarında çağırmayın
- Hooks'ları sıralı çağırın: Her render'da aynı sırada çağrılmalıdır
Sonuç
Hooks kullanarak, React uygulamalarınızı daha temiz ve maintainable hale getirebilirsiniz. Bu modern yaklaşım, class component'lerin karmaşıklığını ortadan kaldırıyor ve fonksiyonel programlama paradigmasını destekliyor.
useState, useEffect, useContext, useReducer ve custom hooks ile modern React uygulamaları geliştirebilir, kodunuzu daha modüler ve yeniden kullanılabilir hale getirebilirsiniz.