Controlled Components
Events dersinde onChange'i, State dersinde useState'i ayrı ayrı
gördük. Bu ders, ikisini bir araya getiren ve React'te form yazmanın
temel deseni olan controlled component'i anlatıyor.
Controlled Component Nedir?
Normalde bir <input>, kendi değerini kendi içinde (tarayıcının DOM'unda)
tutar -- React bunun farkında bile olmayabilir. Bir controlled
component'te ise input'un değeri React'in state'i tarafından
BELİRLENİR: input, kendi başına bir değer tutmaz, değerini her zaman
state'ten alır.
value ile Input'u State'e Bağlamak
Bir input'u controlled yapmanın ilk adımı, value attribute'unu bir
state değişkenine bağlamak:
import { useState } from "react";
function ControlledInputExample() {
const [text, setText] = useState("");
function handleChange(event) {
setText(event.target.value);
}
return (
<div>
{/* value={text}, input'un ekranda gösterdiği değeri React'in state'i
BELİRLESİN diyor -- input artık kendi başına bir değer tutmuyor,
değerini tamamen `text` state'inden alıyor. */}
<input type="text" value={text} onChange={handleChange} />
<p>Yazdığın: {text}</p>
</div>
);
}
value={text} yazdığımız için, input'ta görünen değer HER ZAMAN text
state'inin o anki değeri. Ama tek başına bu yeterli değil -- kullanıcı
yazı yazdığında da bir şey olması lazım, bunu bir sonraki bölümde
görüyoruz.
onChange ile State'i Güncellemek
value tek başına input'u salt-okunur yapar -- kullanıcı hiçbir şey
yazamaz. State'i güncel tutmak için onChange'i de eklemen gerekir:
import { useState } from "react";
function WhyControlledMattersExample() {
const [text, setText] = useState("");
// Değer state'te olduğu için, kullanıcı her harf yazdığında ekranın
// BAŞKA bir yerinde de anında kullanabiliyoruz -- örneğin karakter
// sayısını ya da büyük harfli önizlemesini göstermek gibi.
return (
<div>
<input
type="text"
value={text}
onChange={(event) => setText(event.target.value)}
placeholder="Bir şey yaz..."
/>
<p>Karakter sayısı: {text.length}</p>
<p>Büyük harf önizleme: {text.toUpperCase()}</p>
</div>
);
}
Her tuş vuruşunda onChange çalışır, setText state'i günceller, React
yeniden render eder, ve input'un value'su bu yeni state'i yansıtır. Bu
döngü (yaz → state güncelle → yeniden render et → input'ta göster) bir
controlled component'in kalbi. Değer state'te olduğu için, aynı anda
ekranın başka bir yerinde de (karakter sayısı, önizleme gibi) anında
kullanabiliyoruz.
Checkbox ve Select ile Controlled Component'ler
Aynı desen, metin input'larıyla sınırlı değil -- checkbox'lar ve select'ler de controlled yapılabilir:
import { useState } from "react";
function ControlledCheckboxExample() {
const [isSubscribed, setIsSubscribed] = useState(false);
// Checkbox'larda value yerine checked kullanılır -- mantık aynı:
// checkbox'ın işaretli olup olmadığını React'in state'i belirliyor.
function handleChange(event) {
setIsSubscribed(event.target.checked);
}
return (
<div>
<label>
<input type="checkbox" checked={isSubscribed} onChange={handleChange} />
Bültene abone ol
</label>
<p>{isSubscribed ? "Abonesin." : "Abone değilsin."}</p>
</div>
);
}
Checkbox'larda value yerine checked kullanılır, ama mantık aynı:
işaretli olup olmadığını React'in state'i belirliyor.
import { useState } from "react";
function ControlledSelectExample() {
const [language, setLanguage] = useState("tr");
return (
<div>
{/* select'ler de aynı desenle kontrol edilir: value + onChange. */}
<select value={language} onChange={(event) => setLanguage(event.target.value)}>
<option value="tr">Türkçe</option>
<option value="en">English</option>
</select>
<p>Seçilen dil: {language}</p>
</div>
);
}
<select> da tıpkı bir metin input'u gibi value ve onChange ile
kontrol edilir.
Neden Controlled Component?
Değeri React'in state'inde tutmanın en somut faydalarından biri, o değer üzerinde kolayca işlem yapabilmen -- örneğin programatik olarak sıfırlamak:
import { useState } from "react";
function ResettingControlledInputExample() {
const [text, setText] = useState("");
function handleClear() {
// Değer state'te olduğu için, input'u temizlemek yalnızca state'i
// sıfırlamak kadar basit -- gerçek DOM elemanına dokunmaya
// (useRef ya da event.target.reset() gibi) hiç gerek yok.
setText("");
}
return (
<div>
<input
type="text"
value={text}
onChange={(event) => setText(event.target.value)}
/>
<button onClick={handleClear}>Temizle</button>
</div>
);
}
Değer state'te olduğu için, input'u temizlemek yalnızca setText("")
kadar basit. Eğer değeri React'in dışında (tarayıcının kendi DOM'unda)
tutsaydık, aynı işi yapmak için bir DOM referansına (useRef) ya da
formun kendi reset() metoduna ihtiyacımız olurdu.
Özet ve Terimler Sözlüğü
Bir controlled component, value (ya da checkbox'larda checked) ile
state'e bağlanan ve onChange ile bu state'i güncel tutan bir form
elemanıdır. Değer her zaman React'in state'inde yaşadığı için, o değeri
okumak, doğrulamak ya da sıfırlamak kolaylaşır -- input'un kendi başına
tuttuğu bir değere güvenmene gerek kalmaz.
Terimler Sözlüğü
Controlled Component — Değeri React'in state'i tarafından belirlenen
ve onChange ile güncellenen bir form elemanı.
Uncontrolled Component — Değerini kendi başına (tarayıcının DOM'unda) tutan, React state'ine bağlı olmayan bir form elemanı.