Component
Component, JavaScript sınıfları olarak tanımlanan React bileşenlerinin temel sınıfıdır. Sınıf bileşenleri hâlâ React tarafından desteklenmektedir, ancak yeni kodda kullanılmasını önermiyoruz.
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}- Başvuru Dokümanı
Componentcontextpropsstateconstructor(props)componentDidCatch(error, info)componentDidMount()componentDidUpdate(prevProps, prevState, snapshot?)componentWillMount()componentWillReceiveProps(nextProps)componentWillUpdate(nextProps, nextState)componentWillUnmount()forceUpdate(callback?)getSnapshotBeforeUpdate(prevProps, prevState)render()setState(nextState, callback?)shouldComponentUpdate(nextProps, nextState, nextContext)UNSAFE_componentWillMount()UNSAFE_componentWillReceiveProps(nextProps, nextContext)UNSAFE_componentWillUpdate(nextProps, nextState)static contextTypestatic defaultPropsstatic getDerivedStateFromError(error)static getDerivedStateFromProps(props, state)
- Kullanım
- Alternatifler
Başvuru Dokümanı
Component
Bir React bileşenini sınıf olarak tanımlamak için yerleşik Component sınıfını genişletin ve bir render metodu tanımlayın:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}Yalnızca render metodu zorunludur, diğer metodlar isteğe bağlıdır.
Aşağıda daha fazla örneğe bakın.
context
Bir sınıf bileşeninin context değeri this.context olarak erişilebilir. Yalnızca static contextType kullanarak hangi context’i almak istediğinizi belirtirseniz kullanılabilir.
Bir sınıf bileşeni aynı anda yalnızca bir context okuyabilir.
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}props
Bir sınıf bileşenine iletilen prop’lar this.props olarak erişilebilir.
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
<Greeting name="Taylor" />state
Bir sınıf bileşeninin state’i this.state olarak erişilebilir. state alanı bir nesne olmalıdır. State’i doğrudan değiştirmeyin (mutate etmeyin). State’i değiştirmek istiyorsanız, yeni state ile setState’i çağırın.
class Counter extends Component {
state = {
age: 42,
};
handleAgeChange = () => {
this.setState({
age: this.state.age + 1
});
};
render() {
return (
<>
<button onClick={this.handleAgeChange}>
Increment age
</button>
<p>You are {this.state.age}.</p>
</>
);
}
}constructor(props)
constructor, sınıf bileşeniniz bağlanmadan (ekrana eklenmeden) önce çalışır. Genellikle React’te constructor yalnızca iki amaç için kullanılır. State bildirmenizi ve sınıf metodlarınızı sınıf örneğine bağlamanızı (bind) sağlar:
class Counter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// ...
}Modern JavaScript sözdizimi kullanıyorsanız, constructor’lara nadiren ihtiyaç duyulur. Bunun yerine, yukarıdaki kodu hem modern tarayıcılar hem de Babel gibi araçlar tarafından desteklenen public sınıf alanı sözdizimi kullanarak yeniden yazabilirsiniz:
class Counter extends Component {
state = { counter: 0 };
handleClick = () => {
// ...
}Bir constructor yan etki veya abonelik içermemelidir.
Parametreler
props: Bileşenin başlangıç prop’ları.
Dönüş Değeri
constructor hiçbir şey döndürmemelidir.
Uyarılar
-
Constructor içinde yan etki veya abonelik çalıştırmayın. Bunun yerine
componentDidMountkullanın. -
Constructor içinde, diğer tüm ifadelerden önce
super(props)çağırmanız gerekir. Bunu yapmazsanız, constructor çalışırkenthis.propsundefinedolacaktır; bu kafa karıştırıcı olabilir ve hatalara neden olabilir. -
Constructor,
this.statedeğerini doğrudan atayabileceğiniz tek yerdir. Diğer tüm metodlarda bunun yerinethis.setState()kullanmanız gerekir. Constructor içindesetStateçağırmayın. -
Sunucu taraflı renderlama kullandığınızda, constructor sunucuda da çalışacak ve ardından
rendermetodu gelecektir. AncakcomponentDidMountveyacomponentWillUnmountgibi yaşam döngüsü metodları sunucuda çalışmaz. -
Strict Mode açık olduğunda, React geliştirme ortamında
constructor’ı iki kez çağırır ve ardından örneklerden birini atar. Bu,constructordışına taşınması gereken kazara oluşan yan etkileri fark etmenize yardımcı olur.
componentDidCatch(error, info)
componentDidCatch tanımlarsanız, bir alt bileşen (uzak alt bileşenler dahil) renderlama sırasında bir hata fırlattığında React bunu çağırır. Bu, hatayı production ortamında bir hata raporlama servisine kaydetmenizi sağlar.
Genellikle, bir hataya yanıt olarak state’i güncellemenize ve kullanıcıya bir hata mesajı görüntülemenize olanak tanıyan static getDerivedStateFromError ile birlikte kullanılır. Bu metodlara sahip bir bileşene Hata Sınırı (Error Boundary) denir.
Parametreler
-
error: Fırlatılan hata. Pratikte genellikle birErrorörneği olacaktır, ancak JavaScript dizeler veya hattanulldahil herhangi bir değerithrowetmeye izin verdiği için bu garanti edilmez. -
info: Hata hakkında ek bilgi içeren bir nesne.componentStackalanı, hatayı fırlatan bileşenin yanı sıra tüm üst bileşenlerinin adlarını ve kaynak konumlarını içeren bir yığın izlemesi (stack trace) içerir. Production ortamında bileşen adları küçültülmüş (minified) olacaktır. Production hata raporlaması kurarsanız, normal JavaScript hata yığınlarında yapacağınız gibi bileşen yığınını kaynak haritalarını (sourcemaps) kullanarak çözümleyebilirsiniz.
Dönüş Değeri
componentDidCatch hiçbir şey döndürmemelidir.
Uyarılar
-
Geçmişte, kullanıcı arayüzünü güncellemek ve yedek hata mesajını görüntülemek için
componentDidCatchiçindesetStateçağırmak yaygındı. Bu,static getDerivedStateFromErrortanımlamak lehine kullanımdan kaldırılmıştır (deprecated). -
React’in production ve geliştirme yapıları,
componentDidCatch’in hataları işleme biçiminde hafifçe farklılık gösterir. Geliştirme ortamında hatalarwindow’a kadar yükselir, bu da herhangi birwindow.onerrorveyawindow.addEventListener('error', callback)ifadesinincomponentDidCatchtarafından yakalanan hataları yakalayacağı anlamına gelir. Production ortamında ise hatalar yükselmez; bu, herhangi bir üst hata işleyicisinin yalnızcacomponentDidCatchtarafından açıkça yakalanmayan hataları alacağı anlamına gelir.
componentDidMount()
componentDidMount metodunu tanımlarsanız, bileşeniniz ekrana eklendiğinde (bağlandığında/mount edildiğinde) React bunu çağırır. Bu, veri getirmeye başlamak, abonelikler kurmak veya DOM node’larını manipüle etmek için yaygın bir yerdir.
componentDidMount uygularsanız, hataları önlemek için genellikle diğer yaşam döngüsü metodlarını da uygulamanız gerekir. Örneğin, componentDidMount bazı state veya prop’ları okuyorsa, değişikliklerini işlemek için componentDidUpdate ve componentDidMount’un yaptığı şeyi temizlemek için componentWillUnmount uygulamanız gerekir.
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}Parametreler
componentDidMount hiçbir parametre almaz.
Dönüş Değeri
componentDidMount hiçbir şey döndürmemelidir.
Uyarılar
-
Strict Mode açık olduğunda, geliştirme ortamında React
componentDidMount’u çağırır, ardından hemencomponentWillUnmount’u çağırır ve sonracomponentDidMount’u tekrar çağırır. Bu,componentWillUnmount’u uygulamayı unuttuğunuzu veya mantığınıncomponentDidMount’un yaptığını tam olarak “yansıtmadığını” fark etmenize yardımcı olur. -
componentDidMountiçinde hemensetStateçağırabilseniz de, mümkün olduğunda bundan kaçınmanız en iyisidir. Bu, ekstra bir renderlama tetikler, ancak tarayıcı ekranı güncellemeden önce gerçekleşir. Bu, bu durumdarenderiki kez çağrılsa bile kullanıcının ara state’i görmeyeceğini garanti eder. Bu kalıbı dikkatli kullanın çünkü genellikle performans sorunlarına neden olur. Çoğu durumda, başlangıç state’iniconstructoriçinde atayabilmeniz gerekir. Ancak, render ettiğiniz bir şeyin boyutuna veya konumuna bağlı olarak bir DOM node’unu ölçmeniz gereken modal ve tooltip gibi durumlar için gerekli olabilir.
componentDidUpdate(prevProps, prevState, snapshot?)
componentDidUpdate metodunu tanımlarsanız, bileşeniniz güncellenmiş prop’lar veya state ile yeniden renderlandıktan hemen sonra React bunu çağırır. Bu metod ilk renderlama için çağrılmaz.
Bir güncellemeden sonra DOM’u manipüle etmek için kullanabilirsiniz. Ayrıca, mevcut prop’ları önceki prop’larla karşılaştırdığınız sürece (örneğin, prop’lar değişmediyse bir ağ isteği gerekli olmayabilir) ağ istekleri yapmak için de yaygın bir yerdir. Genellikle componentDidMount ve componentWillUnmount ile birlikte kullanırsınız:
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}Parametreler
-
prevProps: Güncellemeden önceki prop’lar. Neyin değiştiğini belirlemek içinprevProps’uthis.propsile karşılaştırın. -
prevState: Güncellemeden önceki state. Neyin değiştiğini belirlemek içinprevState’ithis.stateile karşılaştırın. -
snapshot:getSnapshotBeforeUpdateuyguladıysanız,snapshoto metoddan döndürdüğünüz değeri içerecektir. Aksi takdirdeundefinedolacaktır.
Dönüş Değeri
componentDidUpdate hiçbir şey döndürmemelidir.
Uyarılar
-
shouldComponentUpdatetanımlanmışsa vefalsedöndürürsecomponentDidUpdateçağrılmaz. -
componentDidUpdateiçindeki mantık genelliklethis.props’uprevPropsile vethis.state’iprevStateile karşılaştıran koşullarla sarmalanmalıdır. Aksi takdirde sonsuz döngü oluşturma riski vardır. -
componentDidUpdateiçinde hemensetStateçağırabilseniz de, mümkün olduğunda bundan kaçınmanız en iyisidir. Bu, ekstra bir renderlama tetikler, ancak tarayıcı ekranı güncellemeden önce gerçekleşir. Bu, bu durumdarenderiki kez çağrılsa bile kullanıcının ara state’i görmeyeceğini garanti eder. Bu kalıp genellikle performans sorunlarına neden olur, ancak render ettiğiniz bir şeyin boyutuna veya konumuna bağlı olarak bir DOM node’unu ölçmeniz gereken modal ve tooltip gibi nadir durumlar için gerekli olabilir.
componentWillMount()
componentWillReceiveProps(nextProps)
componentWillUpdate(nextProps, nextState)
componentWillUnmount()
componentWillUnmount metodunu tanımlarsanız, bileşeniniz ekrandan kaldırılmadan (unmount edilmeden) önce React bunu çağırır. Bu, veri getirmeyi iptal etmek veya abonelikleri kaldırmak için yaygın bir yerdir.
componentWillUnmount içindeki mantık, componentDidMount içindeki mantığı “yansıtmalıdır”. Örneğin, componentDidMount bir abonelik kuruyorsa, componentWillUnmount o aboneliği temizlemelidir. componentWillUnmount içindeki temizleme mantığı bazı prop’ları veya state’i okuyorsa, eski prop’lara ve state’e karşılık gelen kaynakları (abonelikler gibi) temizlemek için genellikle componentDidUpdate uygulamanız da gerekecektir.
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}Parametreler
componentWillUnmount hiçbir parametre almaz.
Dönüş Değeri
componentWillUnmount hiçbir şey döndürmemelidir.
Uyarılar
- Strict Mode açık olduğunda, geliştirme ortamında React
componentDidMount’u çağırır, ardından hemencomponentWillUnmount’u çağırır ve sonracomponentDidMount’u tekrar çağırır. Bu,componentWillUnmount’u uygulamayı unuttuğunuzu veya mantığınıncomponentDidMount’un yaptığını tam olarak “yansıtmadığını” fark etmenize yardımcı olur.
forceUpdate(callback?)
Bir bileşeni yeniden renderlamaya zorlar.
Genellikle bu gerekli değildir. Bileşeninizin render metodu yalnızca this.props, this.state veya this.context’ten okuyorsa, bileşeniniz veya üst bileşenlerinden biri içinde setState çağırdığınızda otomatik olarak yeniden renderlanır. Ancak bileşeninizin render metodu harici bir veri kaynağından doğrudan okuyorsa, o veri kaynağı değiştiğinde React’e kullanıcı arayüzünü güncellemesini söylemeniz gerekir. forceUpdate bunu yapmanızı sağlar.
forceUpdate’in tüm kullanımlarından kaçınmaya çalışın ve render içinde yalnızca this.props ve this.state’ten okuyun.
Parametreler
- isteğe bağlı
callback: Belirtilirse, React güncelleme uygulandıktan sonra sağladığınızcallback’i çağırır.
Dönüş Değeri
forceUpdate hiçbir şey döndürmez.
Uyarılar
forceUpdateçağırırsanız, ReactshouldComponentUpdateçağırmadan yeniden renderlar.
getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate uygularsanız, React DOM’u güncellemeden hemen önce bunu çağırır. Bileşeninizin potansiyel olarak değiştirilmeden önce DOM’dan bazı bilgileri (örneğin kaydırma konumu) yakalamasını sağlar. Bu yaşam döngüsü metodunun döndürdüğü herhangi bir değer, componentDidUpdate’e parametre olarak iletilir.
Örneğin, güncellemeler sırasında kaydırma konumunu korumak gereken bir sohbet dizisi gibi bir kullanıcı arayüzünde kullanabilirsiniz:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// Are we adding new items to the list?
// Capture the scroll position so we can adjust scroll later.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// If we have a snapshot value, we've just added new items.
// Adjust scroll so these new items don't push the old ones out of view.
// (snapshot here is the value returned from getSnapshotBeforeUpdate)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}Yukarıdaki örnekte, scrollHeight özelliğini doğrudan getSnapshotBeforeUpdate içinde okumak önemlidir. render, UNSAFE_componentWillReceiveProps veya UNSAFE_componentWillUpdate içinde okumak güvenli değildir çünkü bu metodların çağrılması ile React’in DOM’u güncellemesi arasında potansiyel bir zaman aralığı vardır.
Parametreler
-
prevProps: Güncellemeden önceki prop’lar. Neyin değiştiğini belirlemek içinprevProps’uthis.propsile karşılaştırın. -
prevState: Güncellemeden önceki state. Neyin değiştiğini belirlemek içinprevState’ithis.stateile karşılaştırın.
Dönüş Değeri
İstediğiniz herhangi bir türde bir anlık görüntü (snapshot) değeri döndürmelisiniz, veya null. Döndürdüğünüz değer, componentDidUpdate’e üçüncü argüman olarak iletilecektir.
Uyarılar
shouldComponentUpdatetanımlanmışsa vefalsedöndürürsegetSnapshotBeforeUpdateçağrılmaz.
render()
render metodu, bir sınıf bileşenindeki tek zorunlu metoddur.
render metodu, ekranda ne görüntülenmesini istediğinizi belirtmelidir, örneğin:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}React, render’ı herhangi bir anda çağırabilir, bu yüzden belirli bir zamanda çalıştığını varsaymamalısınız. Genellikle render metodu bir JSX parçası döndürmelidir, ancak birkaç başka dönüş türü (dizeler gibi) de desteklenir. Döndürülen JSX’i hesaplamak için render metodu this.props, this.state ve this.context okuyabilir.
render metodunu saf bir fonksiyon olarak yazmalısınız; yani prop’lar, state ve context aynıysa aynı sonucu döndürmelidir. Ayrıca yan etkiler (abonelik kurma gibi) içermemeli veya tarayıcı API’leri ile etkileşime girmemelidir. Yan etkiler ya olay işleyicilerinde ya da componentDidMount gibi metodlarda gerçekleşmelidir.
Parametreler
render hiçbir parametre almaz.
Dönüş Değeri
render, herhangi bir geçerli React node’u döndürebilir. Bu, <div /> gibi React elemanlarını, dizeleri, sayıları, portal’ları, boş node’ları (null, undefined, true ve false) ve React node’larından oluşan dizileri içerir.
Uyarılar
-
render, prop’ların, state’in ve context’in saf bir fonksiyonu olarak yazılmalıdır. Yan etkileri olmamalıdır. -
shouldComponentUpdatetanımlanmışsa vefalsedöndürürserenderçağrılmaz. -
Strict Mode açık olduğunda, React geliştirme ortamında
render’ı iki kez çağırır ve ardından sonuçlardan birini atar. Bu,rendermetodunun dışına taşınması gereken kazara oluşan yan etkileri fark etmenize yardımcı olur. -
renderçağrısı ile ardından gelencomponentDidMountveyacomponentDidUpdateçağrısı arasında bire bir karşılık yoktur. Bazırenderçağrı sonuçları, faydalı olduğunda React tarafından atılabilir.
setState(nextState, callback?)
React bileşeninizin state’ini güncellemek için setState’i çağırın.
class Form extends Component {
state = {
name: 'Taylor',
};
handleNameChange = (e) => {
const newName = e.target.value;
this.setState({
name: newName
});
}
render() {
return (
<>
<input value={this.state.name} onChange={this.handleNameChange} />
<p>Hello, {this.state.name}.</p>
</>
);
}
}setState, bileşen state’ine değişiklikleri kuyruğa alır. React’e bu bileşenin ve alt bileşenlerinin yeni state ile yeniden renderlanması gerektiğini söyler. Bu, etkileşimlere yanıt olarak kullanıcı arayüzünü güncellemenin ana yoludur.
setState’e bir fonksiyon da iletebilirsiniz. Önceki state’e dayalı olarak state güncellemenizi sağlar:
handleIncreaseAge = () => {
this.setState(prevState => {
return {
age: prevState.age + 1
};
});
}Bunu yapmak zorunda değilsiniz, ancak aynı olay sırasında state’i birden çok kez güncellemek istiyorsanız kullanışlıdır.
Parametreler
-
nextState: Bir nesne veya bir fonksiyon.nextStateolarak bir nesne iletirseniz,this.stateile yüzeysel (shallow) olarak birleştirilir.nextStateolarak bir fonksiyon iletirseniz, bir güncelleyici fonksiyonu olarak işlenir. Saf olmalı, bekleyen state ve prop’ları argüman olarak almalı vethis.stateile yüzeysel olarak birleştirilecek nesneyi döndürmelidir. React güncelleyici fonksiyonunuzu bir kuyruğa alır ve bileşeninizi yeniden renderlar. Sonraki renderlama sırasında React, kuyruğa alınmış tüm güncelleyicileri önceki state’e uygulayarak sonraki state’i hesaplar.
-
isteğe bağlı
callback: Belirtilirse, React güncelleme uygulandıktan sonra sağladığınızcallback’i çağırır.
Dönüş Değeri
setState hiçbir şey döndürmez.
Uyarılar
-
setState’i, bileşeni güncellemenin anlık bir komutu yerine bir istek olarak düşünün. Birden fazla bileşen bir olaya yanıt olarak state’lerini güncellediğinde, React güncellemelerini toplu hale getirir ve olayın sonunda tek bir geçişte birlikte yeniden renderlar. Belirli bir state güncellemesinin eşzamanlı olarak uygulanmasını zorlamanız gereken nadir durumlarda,flushSyncile sarmalayabilirsiniz, ancak bu performansı olumsuz etkileyebilir. -
setState,this.state’i hemen güncellemez. Bu,setStateçağrısından hemen sonrathis.stateokumayı potansiyel bir tuzak haline getirir. Bunun yerine, güncellemenin uygulandığından emin olancomponentDidUpdateveya setStatecallbackargümanını kullanın. Önceki state’e dayalı olarak state ayarlamanız gerekiyorsa, yukarıda açıklandığı gibinextState’e bir fonksiyon iletebilirsiniz.
shouldComponentUpdate(nextProps, nextState, nextContext)
shouldComponentUpdate tanımlarsanız, React bir yeniden rendermanın atlanıp atanamayacağını belirlemek için bunu çağırır.
Elle yazmak istediğinizden eminseniz, this.props’u nextProps ile ve this.state’i nextState ile karşılaştırabilir ve güncellemenin atlanabileceğini React’e söylemek için false döndürebilirsiniz.
class Rectangle extends Component {
state = {
isHovered: false
};
shouldComponentUpdate(nextProps, nextState) {
if (
nextProps.position.x === this.props.position.x &&
nextProps.position.y === this.props.position.y &&
nextProps.size.width === this.props.size.width &&
nextProps.size.height === this.props.size.height &&
nextState.isHovered === this.state.isHovered
) {
// Nothing has changed, so a re-render is unnecessary
return false;
}
return true;
}
// ...
}React, yeni prop’lar veya state alındığında renderlama öncesinde shouldComponentUpdate’i çağırır. Varsayılan olarak true döndürür. Bu metod ilk renderlama veya forceUpdate kullanıldığında çağrılmaz.
Parametreler
nextProps: Bileşenin renderlanmak üzere olduğu sonraki prop’lar. Neyin değiştiğini belirlemek içinnextProps’uthis.propsile karşılaştırın.nextState: Bileşenin renderlanmak üzere olduğu sonraki state. Neyin değiştiğini belirlemek içinnextState’ithis.stateile karşılaştırın.nextContext: Bileşenin renderlanmak üzere olduğu sonraki context. Neyin değiştiğini belirlemek içinnextContext’ithis.contextile karşılaştırın. Yalnızcastatic contextTypebelirtirseniz kullanılabilir.
Dönüş Değeri
Bileşenin yeniden renderlanmasını istiyorsanız true döndürün. Bu varsayılan davranıştır.
React’e yeniden rendermanın atlanabileceğini söylemek için false döndürün.
Uyarılar
-
Bu metod yalnızca bir performans optimizasyonu olarak mevcuttur. Bileşeniniz onsuz bozuluyorsa, önce onu düzeltin.
-
shouldComponentUpdate’i elle yazmak yerinePureComponentkullanmayı düşünün.PureComponent, prop’ları ve state’i yüzeysel olarak karşılaştırır ve gerekli bir güncellemeyi atlama şansınızı azaltır. -
shouldComponentUpdateiçinde derin eşitlik kontrolleri veyaJSON.stringifykullanmanızı önermiyoruz. Bu, performansı öngörülemez hale getirir ve her prop ve state’in veri yapısına bağımlı kılar. En iyi durumda, uygulamanıza çok saniyelik duraklamalar ekleme riskiyle karşılaşırsınız; en kötü durumda uygulamayı çökertme riskiniz vardır. -
falsedöndürmek, alt bileşenlerin kendi state’leri değiştiğinde yeniden renderlanmasını engellemez. -
falsedöndürmek, bileşenin yeniden renderlanmayacağını garanti etmez. React dönüş değerini bir ipucu olarak kullanır, ancak başka nedenlerle bileşeninizi yeniden renderlamayı yine de seçebilir.
UNSAFE_componentWillMount()
UNSAFE_componentWillMount tanımlarsanız, React bunu constructor’dan hemen sonra çağırır. Yalnızca tarihsel nedenlerle mevcuttur ve yeni kodda kullanılmamalıdır. Bunun yerine alternatiflerden birini kullanın:
- State’i başlatmak için
state’i bir sınıf alanı olarak bildirin veyaconstructoriçindethis.state’i ayarlayın. - Bir yan etki çalıştırmanız veya abonelik kurmanız gerekiyorsa, o mantığı
componentDidMount’a taşıyın.
Güvensiz yaşam döngülerinden göç örneklerini görün.
Parametreler
UNSAFE_componentWillMount hiçbir parametre almaz.
Dönüş Değeri
UNSAFE_componentWillMount hiçbir şey döndürmemelidir.
Uyarılar
-
Bileşen
static getDerivedStateFromPropsveyagetSnapshotBeforeUpdateuyguluyorsaUNSAFE_componentWillMountçağrılmaz. -
Adlandırmasına rağmen, uygulamanız
Suspensegibi modern React özelliklerini kullanıyorsaUNSAFE_componentWillMount, bileşenin bağlanacağını (mount edileceğini) garanti etmez. Bir renderlama girişimi askıya alınırsa (örneğin, bir alt bileşenin kodu henüz yüklenmediyse), React devam eden ağacı atar ve bir sonraki denemede bileşeni sıfırdan oluşturmaya çalışır. Bu yüzden bu metod “güvensiz”dir. Bağlanmaya (mounting) dayanan kod (abonelik ekleme gibi)componentDidMount’a konulmalıdır. -
UNSAFE_componentWillMount, sunucu taraflı renderlama sırasında çalışan tek yaşam döngüsü metodudur. Tüm pratik amaçlar içinconstructorile aynıdır, bu yüzden bu tür mantık içinconstructor’ı kullanmalısınız.
UNSAFE_componentWillReceiveProps(nextProps, nextContext)
UNSAFE_componentWillReceiveProps tanımlarsanız, bileşen yeni prop’lar aldığında React bunu çağırır. Yalnızca tarihsel nedenlerle mevcuttur ve yeni kodda kullanılmamalıdır. Bunun yerine alternatiflerden birini kullanın:
- Prop değişikliklerine yanıt olarak bir yan etki çalıştırmanız gerekiyorsa (örneğin, veri getirme, animasyon çalıştırma veya aboneliği yeniden başlatma), o mantığı
componentDidUpdate’e taşıyın. - Yalnızca bir prop değiştiğinde bazı verileri yeniden hesaplamaktan kaçınmanız gerekiyorsa, bunun yerine bir memoizasyon yardımcısı kullanın.
- Bir prop değiştiğinde bazı state’i “sıfırlamanız” gerekiyorsa, bileşeni tamamen kontrollü veya bir anahtar ile tamamen kontrolsüz yapmayı düşünün.
- Bir prop değiştiğinde bazı state’i “ayarlamanız” gerekiyorsa, renderlama sırasında yalnızca prop’lardan gerekli tüm bilgileri hesaplayıp hesaplayamayacağınızı kontrol edin. Yapamıyorsanız, bunun yerine
static getDerivedStateFromPropskullanın.
Güvensiz yaşam döngülerinden göç örneklerini görün.
Parametreler
nextProps: Bileşenin üst bileşeninden almak üzere olduğu sonraki prop’lar. Neyin değiştiğini belirlemek içinnextProps’uthis.propsile karşılaştırın.nextContext: Bileşenin en yakın sağlayıcıdan almak üzere olduğu sonraki context. Neyin değiştiğini belirlemek içinnextContext’ithis.contextile karşılaştırın. Yalnızcastatic contextTypebelirtirseniz kullanılabilir.
Dönüş Değeri
UNSAFE_componentWillReceiveProps hiçbir şey döndürmemelidir.
Uyarılar
-
Bileşen
static getDerivedStateFromPropsveyagetSnapshotBeforeUpdateuyguluyorsaUNSAFE_componentWillReceivePropsçağrılmaz. -
Adlandırmasına rağmen, uygulamanız
Suspensegibi modern React özelliklerini kullanıyorsaUNSAFE_componentWillReceiveProps, bileşenin bu prop’ları alacağını garanti etmez. Bir renderlama girişimi askıya alınırsa (örneğin, bir alt bileşenin kodu henüz yüklenmediyse), React devam eden ağacı atar ve bir sonraki denemede bileşeni sıfırdan oluşturmaya çalışır. Bir sonraki renderlama denemesinde prop’lar farklı olabilir. Bu yüzden bu metod “güvensiz”dir. Yalnızca kaydedilmiş (committed) güncellemeler için çalışması gereken kod (abonelik sıfırlama gibi)componentDidUpdate’e konulmalıdır. -
UNSAFE_componentWillReceiveProps, bileşenin son seferden farklı prop’lar aldığı anlamına gelmez. Bir şeyin değişip değişmediğini kontrol etmek içinnextPropsvethis.props’u kendiniz karşılaştırmanız gerekir. -
React, bağlanma (mounting) sırasında ilk prop’larla
UNSAFE_componentWillReceiveProps’u çağırmaz. Bu metodu yalnızca bileşenin prop’larından bazıları güncellenecekse çağırır. Örneğin,setStateçağırmak genellikle aynı bileşen içindeUNSAFE_componentWillReceiveProps’u tetiklemez.
UNSAFE_componentWillUpdate(nextProps, nextState)
UNSAFE_componentWillUpdate tanımlarsanız, React yeni prop’lar veya state ile renderlamadan önce bunu çağırır. Yalnızca tarihsel nedenlerle mevcuttur ve yeni kodda kullanılmamalıdır. Bunun yerine alternatiflerden birini kullanın:
- Prop veya state değişikliklerine yanıt olarak bir yan etki çalıştırmanız gerekiyorsa (örneğin, veri getirme, animasyon çalıştırma veya aboneliği yeniden başlatma), o mantığı
componentDidUpdate’e taşıyın. - DOM’dan bazı bilgileri (örneğin, mevcut kaydırma konumunu kaydetmek için) okumak istiyorsanız ve
componentDidUpdateiçinde kullanmak üzere saklayacaksanız, bunun yerinegetSnapshotBeforeUpdateiçinde okuyun.
Güvensiz yaşam döngülerinden göç örneklerini görün.
Parametreler
nextProps: Bileşenin renderlanmak üzere olduğu sonraki prop’lar. Neyin değiştiğini belirlemek içinnextProps’uthis.propsile karşılaştırın.nextState: Bileşenin renderlanmak üzere olduğu sonraki state. Neyin değiştiğini belirlemek içinnextState’ithis.stateile karşılaştırın.
Dönüş Değeri
UNSAFE_componentWillUpdate hiçbir şey döndürmemelidir.
Uyarılar
-
shouldComponentUpdatetanımlanmışsa vefalsedöndürürseUNSAFE_componentWillUpdateçağrılmaz. -
Bileşen
static getDerivedStateFromPropsveyagetSnapshotBeforeUpdateuyguluyorsaUNSAFE_componentWillUpdateçağrılmaz. -
componentWillUpdatesırasındasetState(veyasetState’in çağrılmasına yol açan herhangi bir metod, örneğin bir Redux eylemi göndermek) çağırmak desteklenmez. -
Adlandırmasına rağmen, uygulamanız
Suspensegibi modern React özelliklerini kullanıyorsaUNSAFE_componentWillUpdate, bileşenin güncelleneceğini garanti etmez. Bir renderlama girişimi askıya alınırsa (örneğin, bir alt bileşenin kodu henüz yüklenmediyse), React devam eden ağacı atar ve bir sonraki denemede bileşeni sıfırdan oluşturmaya çalışır. Bir sonraki renderlama denemesinde prop’lar ve state farklı olabilir. Bu yüzden bu metod “güvensiz”dir. Yalnızca kaydedilmiş (committed) güncellemeler için çalışması gereken kod (abonelik sıfırlama gibi)componentDidUpdate’e konulmalıdır. -
UNSAFE_componentWillUpdate, bileşenin son seferden farklı prop’lar veya state aldığı anlamına gelmez. Bir şeyin değişip değişmediğini kontrol etmek içinnextProps’uthis.propsile venextState’ithis.stateile kendiniz karşılaştırmanız gerekir. -
React, bağlanma (mounting) sırasında ilk prop’lar ve state ile
UNSAFE_componentWillUpdate’i çağırmaz.
static contextType
Sınıf bileşeninizden this.context okumak istiyorsanız, hangi context’i okuması gerektiğini belirtmelisiniz. static contextType olarak belirttiğiniz context, daha önce createContext ile oluşturulmuş bir değer olmalıdır.
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}static defaultProps
Sınıf için varsayılan prop’ları ayarlamak üzere static defaultProps tanımlayabilirsiniz. undefined ve eksik prop’lar için kullanılırlar, ancak null prop’lar için kullanılmazlar.
Örneğin, color prop’unun varsayılan olarak 'blue' olması gerektiğini şu şekilde tanımlarsınız:
class Button extends Component {
static defaultProps = {
color: 'blue'
};
render() {
return <button className={this.props.color}>click me</button>;
}
}color prop’u sağlanmazsa veya undefined ise, varsayılan olarak 'blue' ayarlanır:
<>
{/* this.props.color is "blue" */}
<Button />
{/* this.props.color is "blue" */}
<Button color={undefined} />
{/* this.props.color is null */}
<Button color={null} />
{/* this.props.color is "red" */}
<Button color="red" />
</>static getDerivedStateFromError(error)
static getDerivedStateFromError tanımlarsanız, bir alt bileşen (uzak alt bileşenler dahil) renderlama sırasında bir hata fırlattığında React bunu çağırır. Bu, kullanıcı arayüzünü temizlemek yerine bir hata mesajı görüntülemenizi sağlar.
Genellikle, hata raporunu bir analiz servisine göndermenizi sağlayan componentDidCatch ile birlikte kullanılır. Bu metodlara sahip bir bileşene Hata Sınırı (Error Boundary) denir.
Parametreler
error: Fırlatılan hata. Pratikte genellikle birErrorörneği olacaktır, ancak JavaScript dizeler veya hattanulldahil herhangi bir değerithrowetmeye izin verdiği için bu garanti edilmez.
Dönüş Değeri
static getDerivedStateFromError, bileşene hata mesajını görüntülemesini söyleyen state’i döndürmelidir.
Uyarılar
static getDerivedStateFromErrorsaf bir fonksiyon olmalıdır. Bir yan etki gerçekleştirmek istiyorsanız (örneğin, bir analiz servisini çağırmak),componentDidCatch’i de uygulamanız gerekir.
static getDerivedStateFromProps(props, state)
static getDerivedStateFromProps tanımlarsanız, React bunu hem ilk bağlanmada (mount) hem de sonraki güncellemelerde render’ı çağırmadan hemen önce çağırır. State’i güncellemek için bir nesne döndürmeli veya hiçbir şeyi güncellememek için null döndürmelidir.
Bu metod, state’in zaman içindeki prop değişikliklerine bağlı olduğu nadir kullanım durumları için mevcuttur. Örneğin, bu Form bileşeni userID prop’u değiştiğinde email state’ini sıfırlar:
class Form extends Component {
state = {
email: this.props.defaultEmail,
prevUserID: this.props.userID
};
static getDerivedStateFromProps(props, state) {
// Any time the current user changes,
// Reset any parts of state that are tied to that user.
// In this simple example, that's just the email.
if (props.userID !== state.prevUserID) {
return {
prevUserID: props.userID,
email: props.defaultEmail
};
}
return null;
}
// ...
}Bu kalıbın, state’te prop’un önceki bir değerini (örneğin prevUserID gibi userID) tutmanızı gerektirdiğini unutmayın.
Parametreler
props: Bileşenin renderlanmak üzere olduğu sonraki prop’lar.state: Bileşenin renderlanmak üzere olduğu sonraki state.
Dönüş Değeri
static getDerivedStateFromProps, state’i güncellemek için bir nesne döndürür veya hiçbir şeyi güncellememek için null döndürür.
Uyarılar
-
Bu metod, nedeni ne olursa olsun her renderlamada tetiklenir. Bu, yalnızca üst bileşenin yeniden renderlamaya neden olduğunda tetiklenen ve yerel
setStatesonucu olarak tetiklenmeyenUNSAFE_componentWillReceiveProps’tan farklıdır. -
Bu metod, bileşen örneğine erişime sahip değildir. İsterseniz,
static getDerivedStateFromPropsve diğer sınıf metodları arasında, bileşen prop’larının ve state’inin saf fonksiyonlarını sınıf tanımının dışında çıkararak bazı kodları yeniden kullanabilirsiniz.
Kullanım
Bir sınıf bileşeni tanımlama
Bir React bileşenini sınıf olarak tanımlamak için yerleşik Component sınıfını genişletin ve bir render metodu tanımlayın:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}React, ekranda ne görüntüleneceğini belirlemesi gerektiğinde render metodunuzu çağırır. Genellikle ondan bir JSX döndürürsünüz. render metodunuz saf bir fonksiyon olmalıdır: yalnızca JSX’i hesaplamalıdır.
Fonksiyon bileşenlerine benzer şekilde, bir sınıf bileşeni üst bileşeninden prop’lar aracılığıyla bilgi alabilir. Ancak prop’ları okuma sözdizimi farklıdır. Örneğin, üst bileşen <Greeting name="Taylor" /> renderlarsa, name prop’unu this.props’tan, yani this.props.name olarak okuyabilirsiniz:
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
Hook’ların (use ile başlayan fonksiyonlar, örneğin useState) sınıf bileşenleri içinde desteklenmediğini unutmayın.
Bir sınıf bileşenine state ekleme
Bir sınıfa state eklemek için state adlı bir özelliğe bir nesne atayın. State’i güncellemek için this.setState çağırın.
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Taylor', age: 42, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = () => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Increment age </button> <p>Hello, {this.state.name}. You are {this.state.age}.</p> </> ); } }
Bir sınıf bileşenine yaşam döngüsü metodları ekleme
Sınıfınızda tanımlayabileceğiniz birkaç özel metod vardır.
componentDidMount metodunu tanımlarsanız, bileşeniniz ekrana eklendiğinde (bağlandığında/mount edildiğinde) React bunu çağırır. React, bileşeniniz değişen prop’lar veya state nedeniyle yeniden renderlandıktan sonra componentDidUpdate’i çağırır. React, bileşeniniz ekrandan kaldırıldıktan (unmount edildikten) sonra componentWillUnmount’u çağırır.
componentDidMount uygularsanız, hataları önlemek için genellikle üç yaşam döngüsünü de uygulamanız gerekir. Örneğin, componentDidMount bazı state veya prop’ları okuyorsa, değişikliklerini işlemek için componentDidUpdate’i ve componentDidMount’un yaptığı şeyi temizlemek için componentWillUnmount’u da uygulamanız gerekir.
Örneğin, bu ChatRoom bileşeni bir sohbet bağlantısını prop’lar ve state ile senkronize tutar:
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> Server URL:{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Welcome to the {this.props.roomId} room!</h1> </> ); } }
Geliştirme ortamında Strict Mode açık olduğunda, React’in componentDidMount’u çağıracağını, ardından hemen componentWillUnmount’u çağıracağını ve sonra componentDidMount’u tekrar çağıracağını unutmayın. Bu, componentWillUnmount’u uygulamayı unuttuğunuzu veya mantığının componentDidMount’un yaptığını tam olarak “yansıtmadığını” fark etmenize yardımcı olur.
Renderlama hatalarını bir Hata Sınırı ile yakalama
Varsayılan olarak, uygulamanız renderlama sırasında bir hata fırlatırsa, React kullanıcı arayüzünü ekrandan kaldırır. Bunu önlemek için, kullanıcı arayüzünüzün bir bölümünü bir Hata Sınırı (Error Boundary) ile sarmalayabilirsiniz. Hata Sınırı, çöken kısmın yerine bazı yedek kullanıcı arayüzünü — örneğin bir hata mesajını — görüntülemenizi sağlayan özel bir bileşendir.
Bir Hata Sınırı bileşeni uygulamak için, bir hataya yanıt olarak state’i güncellemenize ve kullanıcıya bir hata mesajı görüntülemenize olanak tanıyan static getDerivedStateFromError sağlamanız gerekir. Ayrıca isteğe bağlı olarak componentDidCatch’i uygulayarak ekstra mantık ekleyebilirsiniz, örneğin hatayı bir analiz servisine kaydetmek için.
captureOwnerStack ile geliştirme sırasında Sahip Yığınını (Owner Stack) dahil edebilirsiniz.
import * as React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, info) {
logErrorToMyService(
error,
// Example "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
info.componentStack,
// Warning: `captureOwnerStack` is not available in production.
React.captureOwnerStack(),
);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return this.props.fallback;
}
return this.props.children;
}
}Ardından bileşen ağacınızın bir bölümünü onunla sarmalayabilirsiniz:
<ErrorBoundary fallback={<p>Something went wrong</p>}>
<Profile />
</ErrorBoundary>Profile veya alt bileşeni bir hata fırlatırsa, ErrorBoundary o hatayı “yakalar”, sağladığınız hata mesajıyla birlikte bir yedek kullanıcı arayüzü görüntüler ve hata raporlama servisinize bir production hata raporu gönderir.
Her bileşeni ayrı bir Hata Sınırı ile sarmalamanız gerekmez. Hata Sınırlarının ayrıntı düzeyini düşünürken, bir hata mesajı görüntülemenin nerede mantıklı olacağını değerlendirin. Örneğin, bir mesajlaşma uygulamasında, konuşma listesinin etrafına bir Hata Sınırı yerleştirmek mantıklıdır. Her bir mesajın etrafına da yerleştirmek mantıklıdır. Ancak her avatarın etrafına bir sınır yerleştirmek mantıklı olmaz.
Alternatifler
Basit bir bileşeni sınıftan fonksiyona taşıma
Genellikle, bileşenleri bunun yerine fonksiyon olarak tanımlarsınız.
Örneğin, bu Greeting sınıf bileşenini bir fonksiyona dönüştürdüğünüzü varsayalım:
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
Greeting adlı bir fonksiyon tanımlayın. render fonksiyonunuzun gövdesini buraya taşıyacaksınız.
function Greeting() {
// ... render metodundaki kodu buraya taşıyın ...
}this.props.name yerine, name prop’unu yapısal ayrıştırma sözdizimini kullanarak tanımlayın ve doğrudan okuyun:
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}İşte tam bir örnek:
function Greeting({ name }) { return <h1>Hello, {name}!</h1>; } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
State içeren bir bileşeni sınıftan fonksiyona taşıma
Bu Counter sınıf bileşenini bir fonksiyona dönüştürdüğünüzü varsayalım:
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Taylor', age: 42, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = (e) => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Increment age </button> <p>Hello, {this.state.name}. You are {this.state.age}.</p> </> ); } }
Gerekli state değişkenleriyle bir fonksiyon bildirerek başlayın:
import { useState } from 'react';
function Counter() {
const [name, setName] = useState('Taylor');
const [age, setAge] = useState(42);
// ...Sonra olay işleyicilerini dönüştürün:
function Counter() {
const [name, setName] = useState('Taylor');
const [age, setAge] = useState(42);
function handleNameChange(e) {
setName(e.target.value);
}
function handleAgeChange() {
setAge(age + 1);
}
// ...Son olarak, this ile başlayan tüm referansları bileşeninizde tanımladığınız değişkenler ve fonksiyonlarla değiştirin. Örneğin, this.state.age’i age ile ve this.handleNameChange’i handleNameChange ile değiştirin.
İşte tamamen dönüştürülmüş bileşen:
import { useState } from 'react'; export default function Counter() { const [name, setName] = useState('Taylor'); const [age, setAge] = useState(42); function handleNameChange(e) { setName(e.target.value); } function handleAgeChange() { setAge(age + 1); } return ( <> <input value={name} onChange={handleNameChange} /> <button onClick={handleAgeChange}> Increment age </button> <p>Hello, {name}. You are {age}.</p> </> ) }
Yaşam döngüsü metodlarına sahip bir bileşeni sınıftan fonksiyona taşıma
Yaşam döngüsü metodlarına sahip bu ChatRoom sınıf bileşenini bir fonksiyona dönüştürdüğünüzü varsayalım:
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> Server URL:{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Welcome to the {this.props.roomId} room!</h1> </> ); } }
Önce componentWillUnmount’unuzun componentDidMount’un tersini yaptığını doğrulayın. Yukarıdaki örnekte bu doğrudur: componentDidMount’un kurduğu bağlantıyı keser. Böyle bir mantık eksikse, önce ekleyin.
Sonra, componentDidUpdate metodunuzun componentDidMount’ta kullandığınız tüm prop’lar ve state’deki değişiklikleri işlediğini doğrulayın. Yukarıdaki örnekte, componentDidMount this.state.serverUrl ve this.props.roomId’yi okuyan setupConnection’ı çağırır. Bu yüzden componentDidUpdate, this.state.serverUrl ve this.props.roomId’nin değişip değişmediğini kontrol eder ve değiştiyse bağlantıyı sıfırlar. componentDidUpdate mantığınız eksikse veya ilgili tüm prop’lar ve state’deki değişiklikleri işlemiyorsa, önce düzeltin.
Yukarıdaki örnekte, yaşam döngüsü metodlarının içindeki mantık bileşeni React dışındaki bir sisteme (sohbet sunucusu) bağlar. Bir bileşeni harici bir sisteme bağlamak için bu mantığı tek bir Effect olarak tanımlayın:
import { useState, useEffect } from 'react';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}Bu useEffect çağrısı, yukarıdaki yaşam döngüsü metodlarındaki mantıkla eşdeğerdir. Yaşam döngüsü metodlarınız birbiriyle ilişkisiz birden fazla şey yapıyorsa, bunları birden fazla bağımsız Effect’e bölün. İşte deneyebileceğiniz tam bir örnek:
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; export default function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => { connection.disconnect(); }; }, [roomId, serverUrl]); return ( <> <label> Server URL:{' '} <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} /> </label> <h1>Welcome to the {roomId} room!</h1> </> ); }
Context içeren bir bileşeni sınıftan fonksiyona taşıma
Bu örnekte, Panel ve Button sınıf bileşenleri context’i this.context’ten okur:
import { createContext, Component } from 'react'; const ThemeContext = createContext(null); class Panel extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'panel-' + theme; return ( <section className={className}> <h1>{this.props.title}</h1> {this.props.children} </section> ); } } class Button extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'button-' + theme; return ( <button className={className}> {this.props.children} </button> ); } } function Form() { return ( <Panel title="Welcome"> <Button>Sign up</Button> <Button>Log in</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext value="dark"> <Form /> </ThemeContext> ) }
Bunları fonksiyon bileşenlerine dönüştürdüğünüzde, this.context’i useContext çağrılarıyla değiştirin:
import { createContext, useContext } from 'react'; const ThemeContext = createContext(null); function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ children }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); } function Form() { return ( <Panel title="Welcome"> <Button>Sign up</Button> <Button>Log in</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext value="dark"> <Form /> </ThemeContext> ) }