Formlar
HTML form elemanları, React’te diğer DOM elemanlarından biraz farklı çalışır, çünkü form elemanlarının kendilerine has iç stateleri vardır.
Örneğin, bu kod HTML’de bir form içerisinde name
girişi ister:
<form>
<label>
Adınız:
<input type="text" name="name" />
</label>
<input type="submit" value="Gönder" />
</form>
Kontrollü Componentler
HTML’de, <input>
, <textarea>
ve <select>
gibi form elemanları genellikle kendi state’ini korur ve kullanıcı girdisine dayalı olarak güncelleşir.
React’te ise state’ler genellikle componentlerin this.state
özelliğinde saklanır ve yalnızca setState()
ile güncellenir.
React state’te tek kaynak olarak ikisini birleştirebiliriz.
Ardından form oluşturan React componenti, sonraki kullanıcı girişi üzerinde bu formda olanı da kontrol eder.
Değeri React tarafından bu şekilde kontrol edilen bir giriş form elemanına kontrollü component
denir.
Örneğin, bir önceki örnekte, name
değerinin yazılıp submit edildiğinde name
ı alert ile yazdırmak istiyorsak,
formu kontrollü bir component olarak oluşturabiliriz:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Gönderilen değer: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Gönder" />
</form>
);
}
}
value
attribute’ü input’un kendisinde zaten var.
Öyleyse bu değeri almak için yeni bir React state’i oluşturmaya gerek yok.
Bu inputta value
olarak state’i yazdıracağız ve input’ta her değişiklik olduğunda bu state’i güncelleyeceğiz.
Kontrollü bir componentte her state değişimi, handleChange
fonksiyonunu çalıştıracaktır.
Örneğin, adın büyük harflerle yazılmasını isteseydik, handleChange
fonksiyonunu şu şekilde yazabilirdik:
handleChange(event) {
this.setState({value: event.target.value.toUpperCase()});
}
Buradaki event.target
input’un ta kendisidir.
Bunu fonksiyon içerisinde console.dir(event.target);
yazarak konsoldan doğrulayabilirsiniz.
Haliyle event.target.value
ise o inputtaki değeri alacaktır.</i>
Textarea Tagı
HTML’de, <textarea>
tagı yazıyı çocuğunda tanımlar:
Yani yazılan yazı input
ta olduğu gibi tagın kendisinde değil, tagın içerisindedir.
<textarea>
Merhaba, burası textarea yazı alanıdır.
</textarea>
Bunun yerine React, <textarea>
için bir value
attribute’ü kullanır.
Bu şekilde <textarea>
kullanan bir form, tek satırlı bir girdi kullanan bir forma çok benzer şekilde yazılabilir:
class EssayForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Bu kısma bir şeyler yazınız.'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Gönderilen değer: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Essay:
<textarea value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Gönder" />
</form>
);
}
}
this.state.value
in constructor’te başlatıldığına dikkat edin, böylece textarea
içerisinde varsayılan olarak bu yazı bulunacaktır.
Select Tagı
HTML’de <select>
, bir açılır liste oluşturur. Örneğin, aşağıdaki kod bazı illeri listeler:
<select>
<option value="istanbul">İstanbul</option>
<option value="ankara">Ankara</option>
<option selected value="trabzon">Trabzon</option>
<option value="izmir">İzmir</option>
</select>
Trabzon
seçeneğinin başlangıçta selected
attribute’ü yüzünden seçili olarak geleceğini unutmayın.
React, bu selected
attribute’ünü kullanmak yerine, select
etiketinde bir value
attribute’ü kullanır.
Kontrollü bir componentte bu daha kullanışlıdır çünkü yalnızca bir yerde güncelleme yapmanızı sağlar. Örneğin:
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'Trabzon'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Hangi ilde yaşamak isterdiniz: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
En sevdiğiniz il:
<select value={this.state.value} onChange={this.handleChange}>
<option value="istanbul">İstanbul</option>
<option value="ankara">Ankara</option>
<option value="trabzon">Trabzon</option>
<option value="izmir">İzmir</option>
</select>
</label>
<input type="submit" value="Gönder" />
</form>
);
}
}
Genel olarak bu, <input type="text">
, <textarea>
ve <select>
elementlerinin çok benzer şekilde çalışmasını sağlar.
Not
Bir
select
etiketinde birden fazla seçeneği seçmenize izin veren bir diziyivalue
attribute’üne yazabilirsiniz:<select multiple={true} value={['B', 'C']}>
File Input Tagı
HTML’de <input type="file">
aygıt depolama alanından bir veya daha fazla dosya seçmenizi sağlar.
<input type="file" />
React’te bir <input type="file" />
, önemli bir farkla normal bir <input />
a benzer şekilde çalışır: read-only‘dir.
(Yani yalnızca okunabilirdir, props
lar gibi.)
Çoklu Girişleri Ele Alma
Çoklu kontrollü input
öğelerini ele almanız gerektiğinde,
her öğeye bir name
özniteliği ekleyebilir ve işleyici işlevinin event.target.name
değerine dayanarak ne yapılacağını seçmesine izin verebilirsiniz.
Örneğin:
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
Verilen girdi ismine karşılık gelen state keyini güncellemek için ES6 syntax’ını nasıl kullandığımıza dikkat edin:
this.setState({
[name]: value
});
Buda ES5’teki eşdeğer kodudur.
var partialState = {};
partialState[name] = value;
this.setState(partialState);
Kontrollü Giriş Boş Değer
Kontrollü bir component üzerindeki props’u belirlemek, kullanıcının isteği dışında girişi değiştirmesini önler.
value
belirttiyseniz ancak girdi hala düzenlenebilir ise, yanlışlıkla value
i ` undefined veya
null` olarak ayarlamış olabilirsiniz.
Aşağıdaki kod bunu göstermektedir. (Giriş ilk önce kilitlenir ancak kısa bir gecikme sonrasında düzenlenebilir hale gelir.)
ReactDOM.render(<input value="merhaba" />, mountNode);
setTimeout(function() {
ReactDOM.render(<input value={null} />, mountNode);
}, 1000);