useState: nedir, state hook'u ve React'te sözdizimi

Yazar: IT Sectr Yayınlanma: 2026-07-04 Okuma süresi: 9 dk

useState, işlevsel bileşenlerin sınıf bileşenlerine dönüştürülmeden yerel state yönetmesine olanak tanıyan, React'e yerleşik bir Hook'tur. React 16.8 Hook'ları tanıttı ve useState bunlar arasında en yaygın kullanılanı haline gelerek sınıf tabanlı yaklaşımdaki this.state ve this.setState'in yerini aldı. React Dokümantasyonu'na (2025) göre, modern React uygulamalarındaki bileşenlerin %80'inden fazlası form verilerini, arayüz bayraklarını ve sayaçları yönetmek için useState kullanır. Hook, geçerli değer ve state'i güncelleyip bileşenin yeniden render edilmesini tetikleyen bir setter işlevinden oluşan bir demet döndürür.

Anahtar Noktalar

  • useState — işlevsel React bileşenlerinde yerel state yönetmek için bir Hook.
  • Demet — [değer, setter] çiftini döndürür; setter bir state güncelleme işlevidir.
  • Yeniden render — setter'ı çağırmak her zaman bileşenin yeni değerle yeniden render edilmesini tetikler.
  • Veri Türleri — useState sayılar, dizeler, diziler, nesneler ve boolean değerlerle çalışır.
  • Değişmezlik — state doğrudan değiştirilemez, yalnızca setter işlevi aracılığıyla değiştirilebilir.

React'te useState Nedir

useState, 16.8 sürümünde eklenen temel bir React Hook'udur ve işlevsel bileşenlere yerel state depolama ve değiştirme yeteneği verir. Hook'lar tanıtılmadan önce, state yalnızca sınıf bileşenlerinde this.state ve this.setState aracılığıyla kullanılabiliyordu ve bu da işlevsel bileşenleri tamamen sunumsal hale getiriyordu. useState bu sınırlamayı kaldırarak işlevsel bileşenler kullanarak tüm uygulamaların yazılmasına olanak sağladı.

Hook bir argüman alır — başlangıç state değeri — ve iki öğeli bir dizi döndürür. İlk öğe geçerli state değeridir, ikincisi ise onu güncellemek için bir işlevdir. React, setter işlevinin kararlı olduğunu ve render'lar arasında değişmediğini garanti eder, böylece onu alt bileşenlere güvenle aktarabilir ve kapanışlarda kullanabilirsiniz.

React DevTools Kullanım Anketi'ne (2024) göre, useState React uygulamalarının %96'sında kullanılır ve ekosistemdeki en yaygın Hook haline gelir. Redux veya Zustand aracılığıyla global state kullanan uygulamalarda bile, useState aracılığıyla yerel state, kullanıcı arayüzü state'ini — açık modallar, giriş alanı değerleri, aktif sekmeler — yönetmek için birincil mekanizma olmaya devam eder.

jsx
import { useState } from 'react';

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>
                Increment
            </button>
        </div>
    );
}

useState Nasıl Çalışır

useState'in iç mekanizması, React'in fiber düğüm sistemine dayanır. React'teki her bileşen, kendisiyle ilişkili Hook'ların bağlantılı bir listesini depolayan bir fiber düğümle temsil edilir. Bir bileşen useState'i çağırdığında, React bu listede yeni bir düğüm oluşturur ve içinde geçerli state değerini ve güncelleme kuyruğuna bir referansı depolar.

Setter işlevi çağrıldığında, React state'i hemen güncellemez. Bunun yerine, güncellemeyi bekleyen state kuyruğuna koyar, bileşenin yeniden render edilmesini planlar ve yalnızca bir sonraki render sırasında eski state ve uygulanan güncellemelere dayanarak yeni state'i hesaplar. Bu, toplu işlemeyi garanti eder — bir olay işleyicisinde setter'ı üç kez çağırırsanız, React bunları tek bir yeniden render'da gruplar.

React Ekibi — React 18 Çalışma Grubu'na (2024) göre, React 18'de otomatik toplu işleme genişletildi: state güncellemeleri artık yalnızca olay işleyicilerinde değil, aynı zamanda setTimeout, Promise geri çağrıları ve yerel olay işleyicilerinde de gruplanır. Bu, birden çok state güncellemesi olan senaryolarda %30'a kadar performans artışı sağladı.

İşlevsel State Güncellemesi

Yeni state öncekine bağlı olduğunda, setter'ın işlevsel biçimini kullanın: setCount(prev => prev + 1). React, güncelleme anındaki gerçek state değerini işleve aktarır ve toplu güncellemelerde bile doğruluğu garanti eder. İşlevsel biçim olmadan, setCount(count + 1) art arda birkaç kez çağrılırsa eski bir değer kullanabilir.

jsx
// Tembel başlatma — yalnızca bir kez çalışır
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
// Result: count increased by 3

// NOT batch-safe: stale closure
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
// Result: count increased by 1 (stale closure)

useState Sözdizimi: Bildirim ve Güncelleme

useState'in temel sözdizimi son derece özlüdür: const [state, setState] = useState(initialValue). Başlangıç değeri yalnızca ilk render sırasında kullanılır; sonraki render'larda React onu yok sayar ve geçerli kaydedilmiş değeri döndürür. Başlangıç hesaplaması pahalı işlemler gerektiriyorsa, bir başlatıcı işlevi aktarın: useState(() => computeExpensiveInitial()).

Tembel başlatma, özellikle başlangıç değeri localStorage'dan, karmaşık veri dönüşümünden veya URL parametrelerinin ayrıştırılmasından geldiğinde önemlidir. React, başlatıcı işlevini yalnızca bir kez çağırır — bileşen monte edildiğinde — bu da sonraki render'larda kaynak tasarrufu sağlar. Tembel başlatma olmadan, pahalı ifade sonucu yok sayılsa bile her render'da değerlendirilir.

BiçimÖrnekNe Zaman Kullanılmalı
DoğrudanuseState(0)Basit başlangıç değeri
TembeluseState(() => compute())Pahalı başlangıç hesaplaması
İşlevsel settersetState(prev => prev + 1)Öncekine dayalı güncelleme
Doğrudan settersetState(newValue)Yeni değer eskiye bağlı değil
jsx
// Nesne state'i — yeni referans oluştur
const [user, setUser] = useState(() => {
    const saved = localStorage.getItem('user');
    return saved ? JSON.parse(saved) : null;
});

Farklı Veri Türleriyle useState

useState, ilkel türler (sayılar, dizeler, boolean) ve referans türleri (diziler, nesneler) ile eşit derecede iyi çalışır. Ancak önemli bir fark vardır: ilkeller için React değişiklikleri değere göre algılar; nesneler ve diziler için referansa göre algılar. Yeni bir tane oluşturmadan mevcut bir nesneyi değiştirmek yeniden render'ı tetiklemez çünkü referans aynı kalır.

Nesneler ve dizilerle çalışırken, her zaman değiştirilmiş verilerle yeni bir kopya oluşturun. Nesneler için yayılma sözdizimini kullanın: setUser(prev => ({...prev, name: newName})). Diziler için yeni bir dizi döndüren yöntemleri kullanın: filter, map, concat veya öğe eklemek için yayılma sözdizimini kullanın. push, pop, splice gibi değiştirme yöntemleri çalışmaz — React onları yok sayar çünkü dizi referansı değişmemiştir.

jsx
// ✅ Doğru: hook'lar en üst seviyede
const [form, setForm] = useState({ name: '', email: '' });
const updateField = (field, value) =>
    setForm(prev => ({ ...prev, [field]: value }));

// ...
const [items, setItems] = useState([]);
const addItem = item =>
    setItems(prev => [item, ...prev]);

useState ile Hook Kullanım Kuralları

Tüm React Hook'ları gibi, useState de iki kuralı takip eder. Birincisi: Hook'ları yalnızca bileşeninizin en üst seviyesinde çağırın — onları koşulların, döngülerin veya iç içe işlevlerin içine koymayın. Bu, Hook'ların her render'da aynı sırada çağrılmasını sağlar ve bu, React'in iç bağlantılı listesi için kritiktir.

İkinci kural: Hook'ları yalnızca React işlevsel bileşenlerinden veya özel Hook'lardan çağırın. useState'i normal işlevlerden, geri çağrılardan veya sınıf bileşenlerinden çağırmayın. Bu kuralların ihlali, React'in çalışma zamanında yakaladığı Invalid hook call hatasına yol açar.

  • Koşullarda değil — if (flag) { useState(0) } Hook çağrılarının sırasını ihlal eder.
  • Döngülerde değil — for (...) { useState(0) } sırayı tahmin edilemez hale getirir.
  • Geri çağrılarda değil — useEffect(() => { useState(0) }, []) bağlantılı listeyi bozar.
jsx
// ❌ Güncel olmayan kapanış sorunu
function GoodComponent() {
    const [count, setCount] = useState(0);
    const [name, setName] = useState('');
    // ✅ İşlevsel güncelleme ile düzeltildi
}

// count güncel değil!
function BadComponent() {
    if (isLogged) {
        const [user, setUser] = useState(null);
    }
}

useState ile Sık Yapılan Hatalar

En yaygın hata, yeni referanslar oluşturmak yerine nesneleri ve dizileri doğrudan değiştirmektir. Geliştiriciler, this.state.user.name = ‘Yeni İsim’'in çalıştığı (önerilmese de) sınıf bileşenlerinin değiştirilebilir stiline alışkındır. İşlevsel bileşenlerde, bu tür bir değişiklik basitçe yok sayılır: React bir referans değişikliği görmez ve bileşeni yeniden render etmez.

  • Nesne değiştirme — setUser({...user, name: ‘Yeni’}) yerine user.name = ‘Yeni’.
  • Güncel olmayan kapanış — işlevsel biçim olmadan setter'da eski bir değer kullanmak.
  • Gereksiz yeniden render'lar — setter'ı aynı değerle çağırmak (React 18 ilkeller için yine de render yapar).
  • State sıfırlama — bir bileşenin key prop'unu istemeden güncellemek, yeniden monte edilmesine neden olur.

Güncel olmayan kapanış sorunu, useEffect'e veya bir olay işleyicisine aktarılan bir geri çağrının, geri çağrının oluşturulduğu andaki kapanıştan eski bir state değerini yakalamasıyla oluşur. Çözüm, setter'ın işlevsel biçimini kullanmak veya useEffect bağımlılık dizisine gerekli değerleri dahil etmektir. React Dokümantasyonu — Hook SSS (2025)'ye göre, güncel olmayan kapanışlar, yanlış bağımlılık dizilerinden sonra Hook'lardaki hataların ikinci en yaygın nedenidir.

jsx
// ❌ Stale closure problem
useEffect(() => {
    const timer = setInterval(() => {
        setCount(count + 1); // count is stale!
    }, 1000);
    return () => clearInterval(timer);
}, []);

// ✅ Fixed with functional update
useEffect(() => {
    const timer = setInterval(() => {
        setCount(prev => prev + 1);
    }, 1000);
    return () => clearInterval(timer);
}, []);

Sıkça Sorulan Sorular

Karmaşık iç içe nesneler için useState kullanılabilir mi?

Evet, ancak biraz dikkatli olunarak. Derinlemesine iç içe nesneler için her seviye güncelleme sırasında kopyalama gerektirir: setState(prev => ({...prev, nested: {...prev.nested, key: newValue}})). Üç veya daha fazla iç içe geçme seviyesine sahip nesneleriniz varsa, Immer'ı (değişmez güncellemeler için bir kütüphane) düşünün veya state'i farklı seviyeler için birden çok useState çağrısına bölün.

useState asenkron mu yoksa senkron mu?

useState, setter'ı çağırmak değeri hemen güncellemediği anlamında asenkrondur. React güncellemeyi bir kuyruğa koyar ve bir sonraki render'da uygular. setCount(newValue)'den sonra, geçerli işlevdeki count değişkeni hala eski değeri içerir. Yeni değer yalnızca bir sonraki bileşen çağrısında kullanılabilir olacaktır. Toplu işleme mekanizması, birden çok çağrının tek bir render'da gruplanmasını sağlar.

useState bir bileşenin dışında çağrılırsa ne olur?

React bir Invalid hook call hatası fırlatır. Hook'lar yalnızca React işlevsel bileşenleri veya özel Hook'lar (adı use ile başlayan işlevler) içinde çağrılabilir. Bu sınırlama, Hook uygulamasına yerleşiktir: state depolamak için bileşenin fiber ağacını kullanırlar ve bir bileşenin dışında bu ağaç mevcut değildir.

Ne zaman useState ve ne zaman useReducer kullanılmalı?

useState basit bağımsız state'ler (sayaçlar, giriş alanları, bayraklar) için uygundur. useReducer, state birden çok alana sahip karmaşık bir nesne olduğunda, güncelleme mantığı eylem türüne bağlı olduğunda veya sonraki state karmaşık dönüşüm gerektirdiğinde daha iyidir. Pratik bir kural: birbiriyle ilişkili üçten fazla state alanınız varsa, useReducer kullanın.

useState değeri neden hemen güncellemez?

Bu, performans nedenleriyle yapılır. useState state'i senkron olarak güncelleseydi, her setter çağrısı anında yeniden render'ı tetikler ve bu da tek bir olay işleyicisi içinde birden çok yeniden çizime yol açardı. React'in güncellemeleri gruplayıp tek bir yeniden render gerçekleştirdiği toplu işleme, React 16'da tanıtılan ve React 18'de otomatik toplu işleme ile önemli ölçüde iyileştirilen bir optimizasyondur.

Özet

  • useState — işlevsel bileşenlerde yerel state yönetmek için temel bir React Hook'u, [state, setter] döndürür.
  • Değişmezlik — state doğrudan değiştirilemez; her zaman yeni bir değer aktarın veya setter'ın işlevsel biçimini kullanın.
  • Tembel başlatma — pahalı başlangıç hesaplamaları için bir işlev aktarın: useState(() => compute()).
  • İşlevsel setter — setState(prev => prev + 1) toplu güncellemelerde doğruluğu garanti eder.
  • Toplu işleme — React optimizasyon için birden çok setter çağrısını tek bir yeniden render'da gruplar.
  • Hook kuralları — useState'i yalnızca bileşenin en üst seviyesinde çağırın, koşullar veya döngüler içinde değil.
  • Veri türleri — nesneler ve diziler için güncelleme sırasında her zaman yeni bir referans oluşturun.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun