State

State nedir, useState ile nasıl tanımlanır, nasıl güncellenir, bir önceki state'e göre güncelleme ve state immutability -- basit örneklerle.

Başlangıç 12 dk
EN

State

Events dersinde kullanıcının eylemlerini yakalamayı öğrendik, ama handler'larımız şimdiye kadar yalnızca console.log yazdı -- ekranda hiçbir şey değişmedi. Bu ders, React'te ekranı GERÇEKTEN değiştirmenin yolunu anlatıyor: state.

State Nedir?

State, bir component'in "hatırladığı" ve zamanla değişebilen veridir. State değiştiğinde, React o component'i otomatik olarak yeniden render eder -- yani ekranı güncel state'e göre yeniden çizer. Bir sayaç, bir input'un o anki değeri, bir menünün açık mı kapalı mı olduğu -- bunların hepsi state'e örnek.

useState ile Bir State Tanımlamak

State tanımlamak için useState fonksiyonunu kullanırsın:

import { useState } from "react";

function UseStateBasicExample() {
  // useState(0), state'i 0 başlangıç değeriyle kurar.
  // count: mevcut değeri okumak için. setCount: değeri güncellemek için.
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Sayaç: {count}</p>
      <button onClick={() => setCount(count + 1)}>Artır</button>
    </div>
  );
}

useState(0), state'i 0 başlangıç değeriyle kurar ve iki şey döndürür: mevcut değeri (count) ve onu güncellemek için bir fonksiyon (setCount). const [count, setCount] = ... yazımı, bu iki değeri tek satırda ayrı değişkenlere ayıran bir JavaScript özelliği (array destructuring) -- Props dersindeki nesne destructuring'ine benzer, ama dizi için.

State Güncellemek

State'i değiştirmek için doğrudan count = count + 1 yazamazsın -- bunun yerine useState'in verdiği fonksiyonu (setCount) çağırman gerekir:

import { useState } from "react";

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

  function increment() {
    setCount(count + 1);
  }

  function reset() {
    setCount(0);
  }

  return (
    <div>
      <p>Sayaç: {count}</p>
      <button onClick={increment}>+1</button>
      <button onClick={reset}>Sıfırla</button>
    </div>
  );
}

setCount(...) çağrıldığında React iki şey yapar: state'in yeni değerini kaydeder, ve component'i o yeni değerle yeniden render eder. Doğrudan bir değişkene atama yapmak React'e "bir şey değişti" demediği için ekranı güncellemez -- bunu State vs Normal Değişken bölümünde göreceğiz.

Bir Önceki State'e Göre Güncelleme

Yeni state'i hesaplarken bir önceki state'e ihtiyacın varsa, setCount'a doğrudan bir değer yerine bir FONKSİYON vermelisin:

import { useState } from "react";

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

  function incrementTwice() {
    // YANLIŞ: count burada hâlâ ESKİ değeri gösterir, iki satır da aynı
    // "eski değer + 1"i kullanır -- sonuçta yalnızca 1 artar, 2 değil.
    // setCount(count + 1);
    // setCount(count + 1);

    // DOĞRU: fonksiyon formu (prevCount => ...), her seferinde bir önceki
    // güncellemeden sonraki en güncel değeri kullanır.
    setCount((prevCount) => prevCount + 1);
    setCount((prevCount) => prevCount + 1);
  }

  return (
    <div>
      <p>Sayaç: {count}</p>
      <button onClick={incrementTwice}>2 Artır</button>
    </div>
  );
}

setCount(count + 1) yazmak, aynı render içinde birden fazla kez çağrılırsa güvenilir değildir -- count değişkeni, o render sırasında sabit kalır. setCount((prevCount) => prevCount + 1) yazmak ise React'e "her ne olursa olsun, EN GÜNCEL değere göre hesapla" der.

State vs Normal Değişken

Neden let ile normal bir değişken kullanmıyoruz? Çünkü normal bir değişkeni değiştirmek ekranı güncellemez:

function StateVsVariableExample() {
  let plainCount = 0; // Normal bir değişken -- state DEĞİL.

  function handleClick() {
    plainCount = plainCount + 1;
    console.log("plainCount şimdi:", plainCount);
    // Değer aslında değişti, ama ekranda hiçbir şey güncellenmez --
    // çünkü React, normal bir değişkenin değiştiğini bilmiyor.
  }

  return (
    <div>
      <p>Ekrandaki değer hep aynı kalır: {plainCount}</p>
      <button onClick={handleClick}>Artır (Ekran Değişmez)</button>
    </div>
  );
}

plainCount gerçekten değişiyor (console'da görebilirsin), ama React bunu bilmediği için component'i yeniden render etmiyor -- ekranda hep aynı değer kalıyor. useState özel çünkü React'e "bu değer değiştiğinde beni haberdar et" demiş oluyorsun.

State Immutability (Değişmezlik)

State bir nesne ya da diziyse, onu doğrudan değiştirmek (mutate etmek) yerine her zaman YENİ bir nesne/dizi oluşturup set fonksiyonuna vermelisin:

import { useState } from "react";

function StateImmutabilityExample() {
  const [user, setUser] = useState({ name: "Ayşe", age: 25 });

  function haveBirthday() {
    // YANLIŞ: mevcut nesneyi doğrudan değiştirmek (mutate etmek).
    // React bu değişikliği fark etmeyebilir, ekran güncellenmeyebilir.
    // user.age = user.age + 1;
    // setUser(user);

    // DOĞRU: spread (...) ile eski değerleri kopyalayan YENİ bir nesne
    // oluşturup onu state'e veriyoruz.
    setUser({ ...user, age: user.age + 1 });
  }

  return (
    <div>
      <p>
        {user.name}, {user.age} yaşında.
      </p>
      <button onClick={haveBirthday}>Doğum Günü</button>
    </div>
  );
}

user.age = user.age + 1 yazıp aynı nesneyi geri vermek, React'in değişikliği fark etmesini garanti etmez -- React, state'in "aynı nesne mi farklı bir nesne mi" olduğuna bakarak yeniden render edip etmeyeceğine karar verir. Spread operatörü ({ ...user, age: ... }), eski nesnenin tüm alanlarını kopyalayıp yalnızca belirttiğin alanı değiştiren yeni bir nesne oluşturur.

Özet ve Terimler Sözlüğü

State, bir component'in zamanla değişebilen ve değiştiğinde ekranı otomatik güncelleyen verisidir. useState ile tanımlanır, yalnızca set fonksiyonuyla güncellenir -- doğrudan atama işe yaramaz. Bir önceki state'e göre güncelleme yaparken fonksiyon formu kullanılır. Nesne/dizi state'ler asla doğrudan değiştirilmez (mutate edilmez), her zaman yeni bir kopya oluşturulur.

Terimler Sözlüğü

State — Bir component'in zamanla değişebilen, değiştiğinde component'in yeniden render edilmesini tetikleyen verisi.

useState — Bir component'e state eklemeni sağlayan React fonksiyonu; mevcut değeri ve onu güncelleyen bir fonksiyonu döndürür.

Re-render (Yeniden Render) — React'in, state ya da props değiştiğinde component'i yeniden çalıştırıp ekranı güncellemesi.

Immutability (Değişmezlik) — Mevcut bir nesneyi/diziyi doğrudan değiştirmek yerine, değişikliği içeren yeni bir kopya oluşturma ilkesi.