Bileşenlere Prop'ları Aktarma
React bileşenleri, birbirleriyle iletişim kurmak için prop’ları kullanır. Her üst eleman, alt elemanlarına prop’lar vererek onlarla bilgi paylaşabilir. Prop’lar, size HTML özelliklerini hatırlatabilir, ancak onların aracılığıyla nesneler, diziler ve fonksiyonlar da dahil olmak üzere herhangi bir JavaScript değeri aktarabilirsiniz.
Bunları öğreneceksiniz
- Bileşene prop nasıl aktarılır
- Bir bileşenden prop nasıl okunur
- Prop’lar için varsayılan değerler nasıl belirlenir
- Bir bileşene JSX nasıl aktarılır
- Prop’ların zamanla nasıl değiştiği
Tanıdık Prop’lar
Prop’lar, JSX etiketine ilettiğiniz bilgilerdir. Örneğin, className
, src
, alt
, width
ve height
, bir <img>
’ye aktarabileceğiniz prop’lardan bazılarıdır:
function Avatar() { return ( <img className="avatar" src="https://i.imgur.com/1bX5QH6.jpg" alt="Lin Lanying" width={100} height={100} /> ); } export default function Profile() { return ( <Avatar /> ); }
Bir <img>
etiketine aktarabileceğiniz prop’lar önceden tanımlanmıştır (ReactDOM, HTML standardına uygundur). Ancak, özelleştirmek için <Avatar>
gibi kendi bileşenlerinize herhangi bir özellik aktarabilirsiniz. İşte nasıl!
Bileşene prop’lar aktarma
Bu kodda, Profile
bileşeni, Avatar
adlı alt bileşenine herhangi bir prop aktarmıyor:
export default function Profile() {
return (
<Avatar />
);
}
Avatar
’a iki adımda prop’lar ekleyebilirsiniz.
Adım 1: Alt bileşene prop’lar aktarma
Öncelikle, Avatar
’a bazı prop’lar ekleyin. Örneğin, iki prop ekleyelim: person
(bir nesne) ve size
(bir sayı):
export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}
Şimdi bu prop’ları Avatar
bileşeni içinde okuyabilirsiniz.
Adım 2: Alt eleman içinde prop’ları okuma
Bu prop’ları, function Avatar
’dan hemen sonra ({
ve })
içinde virgülle ayrılan person, size
isimlerini yazarak okuyabilirsiniz. Bu, onları Avatar
kodunun içinde bir değişken gibi kullanmanıza olanak tanır.
function Avatar({ person, size }) {
// burada person ve size kullanılabilir
}
Avatar
’a, person
ve size
prop’larını kullanarak render etmek için biraz mantık ekleyin ve hazırsınız.
Artık Avatar
’ı farklı prop’larla birçok farklı şekilde render etmek için yapılandırabilirsiniz. Değerler ile oynamayı deneyin!
import { getImageUrl } from './utils.js'; function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } export default function Profile() { return ( <div> <Avatar size={100} person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> <Avatar size={80} person={{ name: 'Aklilu Lemma', imageId: 'OKS67lh' }} /> <Avatar size={50} person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }} /> </div> ); }
Prop’lar, üst ve alt bileşenleri bağımsız olarak düşünmenize olanak tanır. Örneğin, Avatar
’ın bunları nasıl kullandığını düşünmeden, Profile
içindeki person
veya size
prop’larını değiştirebilirsiniz. Benzer şekilde, Profile
’a bakmadan, Avatar
’ın bu prop’ları nasıl kullandığını değiştirebilirsiniz.
Prop’ları ayarlayabileceğiniz “düğmeler” gibi düşünebilirsiniz. Aslında, prop’lar fonksiyonlara sağlanan argümanlarla aynı rolü üstlenirler - aslında, prop’lar bileşeniniz için tek argümanlardır! React bileşen fonksiyonları, bir props
nesnesi olarak tek bir argümanı kabul ederler:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Genellikle tüm props
nesnesine ihtiyacınız olmaz, bu yüzden onu bireysel prop’lara ayırarak yapıyı çözmeniz gerekir.
Bir prop için varsayılan değeri belirleme
Bir prop’a, belirtilen değer olmadığında geri dönecek varsayılan bir değer vermek isterseniz, parametreden hemen sonra =
ve varsayılan değeri koyarak yapı çözmeyle yapabilirsiniz:
function Avatar({ person, size = 100 }) {
// ...
}
Şimdi, <Avatar person={...} />
size
prop’u belirtilmeden render edilirse, size
100
olarak ayarlanacaktır.
Varsayılan değer yalnızca, size
prop’u eksikse veya size={undefined}
olarak geçirilirse kullanılır. Ancak size={null}
veya size={0}
olarak geçirirseniz, varsayılan değer kullanılmaz.
JSX yayılım sözdizimiyle prop’ları iletmek
Bazı durumlarda, prop’ları aktarmak çok tekrar edici olabilir:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
Tekrarlayan kodda yanlış olan bir şey yoktur. Daha okunaklı olabilir. Ancak bazen kısa ve öz olmaya önem verirsiniz. Bazı bileşenler, bu Profile
bileşeninin Avatar
ile yaptığı gibi, tüm prop’larını alt elemanlarına iletirler. Doğrudan hiçbir prop kullanmadıklarından, daha özlü “yayılma (spread)” sözdizimi kullanmak mantıklı olabilir:
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
Bu, her birinin adını listeleyerek Profile
’ın tüm prop’larını Avatar
’a iletiyor.
Spread sözdizimini ölçülü bir şekilde kullanın. Her diğer bileşende bunu kullanıyorsanız, bir şeyler yanlış demektir. Çoğu zaman, bileşenlerinizi ayırmanız ve alt elemanları JSX olarak iletilmesi gerektiği anlamına gelir. Sonraki adımda daha fazlası var!
JSX’i alt eleman olarak aktarma
Dahili tarayıcı etiketlerini iç içe geçirmek yaygındır:
<div>
<img />
</div>
Bazen kendi bileşenlerinizi aynı şekilde iç içe yerleştirmek istersiniz:
<Card>
<Avatar />
</Card>
Bir JSX etiketi içine içerik yerleştirdiğinizde, üst eleman, children
adında bir prop’un içinde bu içeriği alacaktır. Örneğin, aşağıdaki Card
bileşeni, <Avatar />
olarak ayarlanmış bir children
prop’u alacak ve bunu bir sarma divinde render edilecektir:
import Avatar from './Avatar.js'; function Card({ children }) { return ( <div className="card"> {children} </div> ); } export default function Profile() { return ( <Card> <Avatar size={100} person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> </Card> ); }
<Card>
içindeki <Avatar>
’ı bir metinle değiştirerek, Card
bileşeninin herhangi bir iç içe içeriği sarmalayabileceğini görmek için deneyebilirsiniz. İçinde neyin render edildiğini “bilmesi” gerekmez. Bu esnek kalıbı birçok yerde göreceksiniz.
Bir children
prop’una sahip bir bileşeni, üst elemanların istediği JSX ile “doldurabileceği” bir “delik” olarak düşünebilirsiniz. Sıklıkla, görsel sarmalayıcılar için (panel
, grid
vb.) children
prop’u kullanacaksınız.
Rachel Lee Nabors tarafından görselleştirilmiştir.
Aşağıdaki Clock
bileşeni, üst elemandan iki prop alır: color
ve time
. (Üst elemanın kodu, henüz incelemeyeceğimiz durum (state) kullandığı için atlanmıştır.)
Aşağıdaki seçim kutusunda rengi değiştirmeyi deneyin:
export default function Clock({ color, time }) { return ( <h1 style={{ color: color }}> {time} </h1> ); }
Bu örnek, bir bileşenin zamanla farklı prop’lar alabileceğini gösterir. Prop’lar her zaman statik değildir! Burada time
prop’u her saniyede bir değişir ve color
prop’u başka bir renk seçtiğinizde değişir. Prop’lar, bir bileşenin verilerini sadece başlangıçta değil, herhangi bir zamandaki durumunu yansıtır.
Ancak, prop’lar immutable (değiştirilemez) özelliktedir - bilgisayar bilimlerinde “değiştirilemez” anlamına gelen bir terimdir. Bir bileşen, prop’larını değiştirmesi gerektiğinde (örneğin, bir kullanıcı etkileşimine veya yeni verilere yanıt olarak), farklı bir nesne olan farklı prop’ları geçmesi için üst elemanından “istemek” zorunda kalacaktır! Eski prop’ları atılacak ve sonunda JavaScript motoru tarafından bunların işgal ettiği bellek geri alınacaktır.
Prop’ları “değiştirmeye” çalışmayın. Kullanıcı girdisine yanıt vermeniz gerektiğinde (seçilen rengi değiştirme gibi), State: Bir Bileşenin Belleği konusunda öğrenebileceğiniz şekilde “state ayarı” yapmanız gerekecektir.
Özet
- Prop’ları geçmek için, HTML özniteliklerini geçirdiğiniz gibi JSX’e ekleyin.
- Prop’ları okumak için,
function Avatar({ person, size })
yapısını kullanın. - Eksik veya tanımlanmamış prop’lar için kullanılan
size = 100
gibi varsayılan bir değer belirleyebilirsiniz. - Tüm prop’ları
<Avatar {...props} />
JSX spread sözdizimi ile iletebilirsiniz, ancak bunu abartmayın! <Card><Avatar /></Card>
gibi iç içe JSX,Card
bileşenininchildren
prop’u olarak görüntülenecektir.- Prop’lar, her render işlemi bir prop’ların yeni bir sürümünü aldığı için okunur ve değiştirilemez.
- Prop’ları değiştiremezsiniz. Etkileşimli bir bileşen için, state ayarlaması yapmanız gerekecektir.
Problem 1 / 3: Bileşen Ayıklama
Bu Gallery
bileşeni, iki profille ilgili çok benzer bir işaretleme içerir. Yinelemeyi azaltmak için bunun dışında bir Profile
bileşeni çıkarın. Hangi prop’ların geçirileceğine karar vermeniz gerekecektir.
import { getImageUrl } from './utils.js'; export default function Gallery() { return ( <div> <h1>Önemli Bilim İnsanları</h1> <section className="profile"> <h2>Maria Skłodowska-Curie</h2> <img className="avatar" src={getImageUrl('szV5sdG')} alt="Maria Skłodowska-Curie" width={70} height={70} /> <ul> <li> <b>Meslek: </b> fizikçi ve kimyager </li> <li> <b>Ödüller: 4 </b> (Fizik Nobel Ödülü, Kimya Nobel Ödülü, Davy Madalyası, Matteucci Madalyası) </li> <li> <b>Keşfedilenler: </b> polonyum (kimyasal element) </li> </ul> </section> <section className="profile"> <h2>Katsuko Saruhashi</h2> <img className="avatar" src={getImageUrl('YfeOqp2')} alt="Katsuko Saruhashi" width={70} height={70} /> <ul> <li> <b>Meslek: </b> jeokimyager </li> <li> <b>Ödüller: 2 </b> (Miyake Ödülü (jeokimya), Tanaka Ödülü) </li> <li> <b>Keşfedilenler: </b> deniz suyundaki karbondioksit ölçüm yöntemi </li> </ul> </section> </div> ); }