diff --git a/.gitignore b/.gitignore index d8bec488b..4278f9b22 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ yarn-error.log* # external fonts public/fonts/**/Optimistic_*.woff2 + +# IDE +.idea \ No newline at end of file diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index a897a602b..dafb7f129 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -1,37 +1,37 @@ --- -title: 'Separating Events from Effects' +title: 'Olayları Efektlerinden Ayırma' --- -Event handlers only re-run when you perform the same interaction again. Unlike event handlers, Effects re-synchronize if some value they read, like a prop or a state variable, is different from what it was during the last render. Sometimes, you also want a mix of both behaviors: an Effect that re-runs in response to some values but not others. This page will teach you how to do that. +Olay yöneticileri yalnızca aynı etkileşimi tekrar gerçekleştirdiğinizde yeniden çalışır. Olay yöneticileri aksine, Efektler bir prop veya state değişkeni gibi okudukları bir değerin son render sırasında olduğundan farklı olması durumunda yeniden senkronize olur. Bazen, her iki davranışın bir karışımını da istersiniz: bazı değerlere yanıt olarak yeniden çalışan ancak diğerlerine yanıt vermeyen bir Efekt. Bu sayfa size bunu nasıl yapacağınızı öğretecek. -- How to choose between an event handler and an Effect -- Why Effects are reactive, and event handlers are not -- What to do when you want a part of your Effect's code to not be reactive -- What Effect Events are, and how to extract them from your Effects -- How to read the latest props and state from Effects using Effect Events +- Bir olay yöneticisi ile bir Efekt arasında nasıl seçim yapılır? +- Efektler neden reaktiftir ve olay yöneticileri değildir? +- Efektinizin kodunun bir bölümünün reaktif olmamasını istediğinizde ne yapmalısınız? +- Efekt olaylarının ne olduğu ve Efektlerinizden nasıl çıkarılacağı +- Efekt olaylarını kullanarak Efektlerden en son sahne ve durum nasıl okunur? -## Choosing between event handlers and Effects {/*choosing-between-event-handlers-and-effects*/} +## Olay yöneticileri ve Efektler arasında seçim yapma {/*choosing-between-event-handlers-and-effects*/} -First, let's recap the difference between event handlers and Effects. +İlk olarak, olay yöneticileri ve Efektler arasındaki farkı özetleyelim. -Imagine you're implementing a chat room component. Your requirements look like this: +Bir sohbet odası bileşeni oluşturduğunuzu düşünün. Gereksinimleriniz şuna benziyor: -1. Your component should automatically connect to the selected chat room. -1. When you click the "Send" button, it should send a message to the chat. +1. Bileşeniniz seçilen sohbet odasına otomatik olarak bağlanmalıdır. +1. "Gönder" düğmesine tıkladığınızda, sohbete bir mesaj göndermelidir. -Let's say you've already implemented the code for them, but you're not sure where to put it. Should you use event handlers or Effects? Every time you need to answer this question, consider [*why* the code needs to run.](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events) +Diyelim ki bunlar için kodu zaten uyguladınız, ancak nereye koyacağınızdan emin değilsiniz. Olay yöneticileri mi yoksa Efektler mi kullanmalısınız? Bu soruyu her yanıtlamanız gerektiğinde, [*neden* kodun çalışması gerektiğini](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events) düşünün. -### Event handlers run in response to specific interactions {/*event-handlers-run-in-response-to-specific-interactions*/} +### Olay yöneticileri belirli etkileşimlere yanıt olarak çalışır {/*event-handlers-run-in-response-to-specific-interactions*/} -From the user's perspective, sending a message should happen *because* the particular "Send" button was clicked. The user will get rather upset if you send their message at any other time or for any other reason. This is why sending a message should be an event handler. Event handlers let you handle specific interactions: +Kullanıcının bakış açısına göre, bir mesajın gönderilmesi belirli bir "Gönder" düğmesine tıklandığı için *olmalıdır*. Mesajlarını başka bir zamanda veya başka bir nedenle gönderirseniz kullanıcı oldukça üzülecektir. İşte bu yüzden mesaj gönderme bir olay yöneticileri olmalıdır. Olay yöneticileri belirli etkileşimleri ele almanızı sağlar: ```js {4-6} function ChatRoom({ roomId }) { @@ -44,19 +44,19 @@ function ChatRoom({ roomId }) { return ( <> setMessage(e.target.value)} /> - ; + ; ); } ``` -With an event handler, you can be sure that `sendMessage(message)` will *only* run if the user presses the button. +Bir olay yöneticileri ile `sendMessage(message)`ın *sadece* kullanıcı düğmeye bastığında çalışacağından emin olabilirsiniz. -### Effects run whenever synchronization is needed {/*effects-run-whenever-synchronization-is-needed*/} +### Senkronizasyon gerektiğinde Efektler çalışır {/*effects-run-whenever-synchronization-is-needed*/} -Recall that you also need to keep the component connected to the chat room. Where does that code go? +Bileşeni sohbet odasına bağlı tutmanız gerektiğini de hatırlayın. Bu kod nereye gidecek? -The *reason* to run this code is not some particular interaction. It doesn't matter why or how the user navigated to the chat room screen. Now that they're looking at it and could interact with it, the component needs to stay connected to the selected chat server. Even if the chat room component was the initial screen of your app, and the user has not performed any interactions at all, you would *still* need to connect. This is why it's an Effect: +Bu kodu çalıştırmak için *neden* belirli bir etkileşim değildir. Kullanıcının sohbet odası ekranına neden veya nasıl gittiği önemli değildir. Artık ona baktıklarına ve onunla etkileşime girebildiklerine göre, bileşenin seçilen sohbet sunucusuna bağlı kalması gerekir. Sohbet odası bileşeni uygulamanızın ilk ekranı olsa ve kullanıcı hiçbir etkileşim gerçekleştirmemiş olsa bile, yine de *bağlanmanız* gerekir. İşte bu yüzden bir Efekttir: ```js {3-9} function ChatRoom({ roomId }) { @@ -72,7 +72,7 @@ function ChatRoom({ roomId }) { } ``` -With this code, you can be sure that there is always an active connection to the currently selected chat server, *regardless* of the specific interactions performed by the user. Whether the user has only opened your app, selected a different room, or navigated to another screen and back, your Effect ensures that the component will *remain synchronized* with the currently selected room, and will [re-connect whenever it's necessary.](/learn/lifecycle-of-reactive-effects#why-synchronization-may-need-to-happen-more-than-once) +Bu kod sayesinde, kullanıcı tarafından gerçekleştirilen belirli etkileşimlerden *bağımsız olarak*, seçili sohbet sunucusuyla her zaman aktif bir bağlantı olduğundan emin olabilirsiniz. Kullanıcı ister sadece uygulamanızı açmış, ister farklı bir oda seçmiş ya da başka bir ekrana gidip geri dönmüş olsun, Efektiniz bileşenin o anda seçili olan odayla *senkronize kalmasını* ve [gerektiğinde yeniden bağlanmasını](/learn/lifecycle-of-reactive-effects#why-synchronization-may-need-to-happen-more-than-once) sağlar. @@ -97,31 +97,31 @@ function ChatRoom({ roomId }) { return ( <> -

Welcome to the {roomId} room!

+

{roomId} odasına hoş geldiniz!

setMessage(e.target.value)} /> - + ); } export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('genel'); const [show, setShow] = useState(false); return ( <> {show &&
} {show && } @@ -132,17 +132,17 @@ export default function App() { ```js chat.js export function sendMessage(message) { - console.log('🔵 You sent: ' + message); + console.log('🔵 Siz gönderdiniz: ' + message); } export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // Gerçek bir uygulama sunucuya gerçekten bağlanır return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ ' + serverUrl + 'adresinde "' + roomId + '" odasina baglaniliyor' + '...'); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ ' + serverUrl + 'adresinde "' + roomId + '" odasının bağlantısı kesildi ' ); } }; } @@ -154,13 +154,13 @@ input, select { margin-right: 20px; }
-## Reactive values and reactive logic {/*reactive-values-and-reactive-logic*/} +## Reaktif değerler ve reaktif mantık {/*reactive-values-and-reactive-logic*/} -Intuitively, you could say that event handlers are always triggered "manually", for example by clicking a button. Effects, on the other hand, are "automatic": they run and re-run as often as it's needed to stay synchronized. +Sezgisel olarak, olay yöneticilerinin her zaman "manuel" olarak tetiklendiğini söyleyebilirsiniz, örneğin bir düğmeye tıklayarak. Öte yandan, Efektler "otomatiktir": senkronize kalmak için gerektiği sıklıkta çalışır ve yeniden çalışırlar. -There is a more precise way to think about this. +Bunu düşünmenin daha kesin bir yolu vardır. -Props, state, and variables declared inside your component's body are called reactive values. In this example, `serverUrl` is not a reactive value, but `roomId` and `message` are. They participate in the rendering data flow: +Bileşeninizin gövdesi içinde bildirilen prop'lar, durum ve değişkenler reaktif değerler olarak adlandırılır. Bu örnekte, `serverUrl` reaktif bir değer değildir, ancak `roomId` ve `message` reaktif değerlerdir. Oluşturma veri akışına katılırlar: ```js [[2, 3, "roomId"], [2, 4, "message"]] const serverUrl = 'https://localhost:1234'; @@ -172,16 +172,16 @@ function ChatRoom({ roomId }) { } ``` -Reactive values like these can change due to a re-render. For example, the user may edit the `message` or choose a different `roomId` in a dropdown. Event handlers and Effects respond to changes differently: +Bunlar gibi reaktif değerler yeniden oluşturma nedeniyle değişebilir. Örneğin, kullanıcı `message`ı düzenleyebilir veya bir açılır menüde farklı bir `roomId` seçebilir. Olay yöneticileri ve Efektler değişikliklere farklı şekilde yanıt verir: -- **Logic inside event handlers is *not reactive.*** It will not run again unless the user performs the same interaction (e.g. a click) again. Event handlers can read reactive values without "reacting" to their changes. -- **Logic inside Effects is *reactive.*** If your Effect reads a reactive value, [you have to specify it as a dependency.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) Then, if a re-render causes that value to change, React will re-run your Effect's logic with the new value. +- **Olay yöneticilerinin içindeki mantık * reaktif değildir.*** Kullanıcı aynı etkileşimi (örneğin bir tıklama) tekrar gerçekleştirmedikçe tekrar çalışmayacaktır. Olay yöneticileri, değişikliklerine "tepki vermeden" reaktif değerleri okuyabilir. +- **Efektlerin içindeki mantık *reaktiftir.*** Efektiniz reaktif bir değeri okuyorsa, [bunu bir bağımlılık olarak belirtmeniz gerekir](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) Ardından, bir yeniden oluşturma bu değerin değişmesine neden olursa, React, Efektinizin mantığını yeni değerle yeniden çalıştıracaktır. -Let's revisit the previous example to illustrate this difference. +Bu farkı göstermek için bir önceki örneğe geri dönelim. -### Logic inside event handlers is not reactive {/*logic-inside-event-handlers-is-not-reactive*/} +### Olay yöneticileri içindeki mantık reaktif değildir {/*logic-inside-event-handlers-is-not-reactive*/} -Take a look at this line of code. Should this logic be reactive or not? +Şu kod satırına bir göz atın. Bu mantık reaktif olmalı mı olmamalı mı? ```js [[2, 2, "message"]] // ... @@ -189,7 +189,7 @@ Take a look at this line of code. Should this logic be reactive or not? // ... ``` -From the user's perspective, **a change to the `message` does _not_ mean that they want to send a message.** It only means that the user is typing. In other words, the logic that sends a message should not be reactive. It should not run again only because the reactive value has changed. That's why it belongs in the event handler: +Kullanıcının bakış açısından, **`message`'da yapılan bir değişiklik, mesaj göndermek istedikleri anlamına gelmez.** Bu sadece kullanıcının yazmakta olduğu anlamına gelir. Başka bir deyişle, mesaj gönderen mantık reaktif olmamalıdır. Sadece reactive value değiştiği için tekrar çalışmamalıdır. Bu yüzden olay yöneticisine aittir: ```js {2} function handleSendClick() { @@ -197,11 +197,11 @@ From the user's perspective, **a change to the `message` does _not_ mean that th } ``` -Event handlers aren't reactive, so `sendMessage(message)` will only run when the user clicks the Send button. +Olay yöneticileri reaktif değildir, bu nedenle `sendMessage(message)` yalnızca kullanıcı Gönder düğmesine tıkladığında çalışacaktır. -### Logic inside Effects is reactive {/*logic-inside-effects-is-reactive*/} +### Efektlerin içindeki mantık reaktiftir {/*logic-inside-effects-is-reactive*/} -Now let's return to these lines: +Şimdi bu satırlara geri dönelim: ```js [[2, 2, "roomId"]] // ... @@ -210,7 +210,7 @@ Now let's return to these lines: // ... ``` -From the user's perspective, **a change to the `roomId` *does* mean that they want to connect to a different room.** In other words, the logic for connecting to the room should be reactive. You *want* these lines of code to "keep up" with the reactive value, and to run again if that value is different. That's why it belongs in an Effect: +Kullanıcının bakış açısından, **`roomId`'deki bir değişiklik farklı bir odaya bağlanmak istedikleri anlamına gelir.** Başka bir deyişle, odaya bağlanma mantığı reaktif olmalıdır. Bu kod satırlarının reaktif değere "ayak uydurmasını" ve bu değer farklıysa yeniden çalışmasını *istiyorsunuz*. Bu yüzden bir Efekte aittir: ```js {2-3} useEffect(() => { @@ -222,13 +222,13 @@ From the user's perspective, **a change to the `roomId` *does* mean that they wa }, [roomId]); ``` -Effects are reactive, so `createConnection(serverUrl, roomId)` and `connection.connect()` will run for every distinct value of `roomId`. Your Effect keeps the chat connection synchronized to the currently selected room. +Efektler reaktiftir, bu nedenle `createConnection(serverUrl, roomId)` ve `connection.connect()`, `roomId`nin her farklı değeri için çalışacaktır. Efektiniz sohbet bağlantısını o anda seçili olan odayla senkronize tutar. -## Extracting non-reactive logic out of Effects {/*extracting-non-reactive-logic-out-of-effects*/} +## Reaktif olmayan mantığı Efektlerden çıkarma {/*extracting-non-reactive-logic-out-of-effects*/} -Things get more tricky when you want to mix reactive logic with non-reactive logic. +Reaktif mantığı reaktif olmayan mantıkla karıştırmak istediğinizde işler daha da zorlaşır. -For example, imagine that you want to show a notification when the user connects to the chat. You read the current theme (dark or light) from the props so that you can show the notification in the correct color: +Örneğin, kullanıcı sohbete bağlandığında bir bildirim göstermek istediğinizi düşünün. Bildirimi doğru renkte gösterebilmek için mevcut temayı (koyu veya açık) prop'lardan okursunuz: ```js {1,4-6} function ChatRoom({ roomId, theme }) { @@ -241,24 +241,24 @@ function ChatRoom({ roomId, theme }) { // ... ``` -However, `theme` is a reactive value (it can change as a result of re-rendering), and [every reactive value read by an Effect must be declared as its dependency.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Now you have to specify `theme` as a dependency of your Effect: +Ancak, `theme` reaktif bir değerdir (yeniden oluşturma sonucunda değişebilir) ve [bir Efekt tarafından okunan her reaktif değerin bağımlılığı olarak bildirilmesi gerekir](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Şimdi `theme` Efektinizin bir bağımlılığı olarak belirtmeniz gerekir: ```js {5,11} function ChatRoom({ roomId, theme }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.on('connected', () => { - showNotification('Connected!', theme); + showNotification('Bağlandı!', theme); }); connection.connect(); return () => { connection.disconnect() }; - }, [roomId, theme]); // ✅ All dependencies declared + }, [roomId, theme]); // ✅ Tüm bağımlılıklar bildirildi // ... ``` -Play with this example and see if you can spot the problem with this user experience: +Bu örnekle oynayın ve bu kullanıcı deneyimindeki sorunu tespit edip edemeyeceğinizi görün: @@ -290,29 +290,29 @@ function ChatRoom({ roomId, theme }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.on('connected', () => { - showNotification('Connected!', theme); + showNotification('Baglandi!', theme); }); connection.connect(); return () => connection.disconnect(); }, [roomId, theme]); - return

Welcome to the {roomId} room!

+ return

{roomId} odasına hoş geldiniz!

} export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('genel'); const [isDark, setIsDark] = useState(false); return ( <>
-When the `roomId` changes, the chat re-connects as you would expect. But since `theme` is also a dependency, the chat *also* re-connects every time you switch between the dark and the light theme. That's not great! +`RoomId` değiştiğinde, sohbet beklediğiniz gibi yeniden bağlanır. Ancak `theme` de bir bağımlılık olduğundan, koyu ve açık tema arasında her geçiş yaptığınızda sohbet *ayrıca* yeniden bağlanır. Bu hiç de iyi değil! -In other words, you *don't* want this line to be reactive, even though it is inside an Effect (which is reactive): +Başka bir deyişle, bir Efektin (reaktif olan) içinde olmasına rağmen bu satırın reaktif olmasını *istemezsiniz*: ```js // ... - showNotification('Connected!', theme); + showNotification('Bağlandı!', theme); // ... ``` -You need a way to separate this non-reactive logic from the reactive Effect around it. +Bu reaktif olmayan mantığı, etrafındaki reaktif Efektten ayırmak için bir yola ihtiyacınız var. -### Declaring an Effect Event {/*declaring-an-effect-event*/} +### Bir Efekt Olayı Bildirme {/*declaring-an-effect-event*/} -This section describes an **experimental API that has not yet been released** in a stable version of React. +Bu bölümde, React'in kararlı bir sürümünde henüz yayınlanmamış **deneysel bir API** açıklanmaktadır. -Use a special Hook called [`useEffectEvent`](/reference/react/experimental_useEffectEvent) to extract this non-reactive logic out of your Effect: +Bu reaktif olmayan mantığı Efektinizden çıkarmak için [`useEffectEvent`](/reference/react/experimental_useEffectEvent) adlı özel bir Hook kullanın: ```js {1,4-6} import { useEffect, useEffectEvent } from 'react'; function ChatRoom({ roomId, theme }) { const onConnected = useEffectEvent(() => { - showNotification('Connected!', theme); + showNotification('Baglandi!', theme); }); // ... ``` -Here, `onConnected` is called an *Effect Event.* It's a part of your Effect logic, but it behaves a lot more like an event handler. The logic inside it is not reactive, and it always "sees" the latest values of your props and state. +Burada, `onConnected` bir *Efekt olayı olarak adlandırılır.* Efekt mantığınızın bir parçasıdır, ancak daha çok bir olay yöneticisi gibi davranır. İçindeki mantık reaktif değildir ve her zaman sahne ve durumunuzun en son değerlerini "görür". -Now you can call the `onConnected` Effect Event from inside your Effect: +Artık `onConnected` Efekt olayını Efektinizin içinden çağırabilirsiniz: ```js {2-4,9,13} function ChatRoom({ roomId, theme }) { const onConnected = useEffectEvent(() => { - showNotification('Connected!', theme); + showNotification('Baglandi!', theme); }); useEffect(() => { @@ -435,13 +435,13 @@ function ChatRoom({ roomId, theme }) { }); connection.connect(); return () => connection.disconnect(); - }, [roomId]); // ✅ All dependencies declared + }, [roomId]); // ✅ Tüm bagimliliklar bildirildi // ... ``` -This solves the problem. Note that you had to *remove* `onConnected` from the list of your Effect's dependencies. **Effect Events are not reactive and must be omitted from dependencies.** +Bu sorunu çözer. Efektinizin bağımlılıkları listesinden `onConnected` öğesini *kaldırmanız* gerektiğini unutmayın. **Efekt olayları reaktif değildir ve bağımlılıklardan çıkarılmalıdır.** -Verify that the new behavior works as you would expect: +Yeni davranışın beklediğiniz gibi çalıştığını doğrulayın: @@ -472,7 +472,7 @@ const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId, theme }) { const onConnected = useEffectEvent(() => { - showNotification('Connected!', theme); + showNotification('Baglandi!', theme); }); useEffect(() => { @@ -484,23 +484,23 @@ function ChatRoom({ roomId, theme }) { return () => connection.disconnect(); }, [roomId]); - return

Welcome to the {roomId} room!

+ return

{roomId} odasına hoş geldiniz!

} export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('genel'); const [isDark, setIsDark] = useState(false); return ( <>
-You can think of Effect Events as being very similar to event handlers. The main difference is that event handlers run in response to a user interactions, whereas Effect Events are triggered by you from Effects. Effect Events let you "break the chain" between the reactivity of Effects and code that should not be reactive. +Efekt olaylarını olay yöneticilerine çok benzer olarak düşünebilirsiniz. Temel fark, olay işleyicilerinin kullanıcı etkileşimlerine yanıt olarak çalışması, Efekt olaylarının ise sizin tarafınızdan Efektlerden tetiklenmesidir. Efekt olayları, Efektlerin tepkiselliği ile tepkisel olmaması gereken kod arasındaki "zinciri kırmanızı" sağlar. -### Reading latest props and state with Effect Events {/*reading-latest-props-and-state-with-effect-events*/} +### Efekt olayları ile en son propları ve state okuma {/*reading-latest-props-and-state-with-effect-events*/} -This section describes an **experimental API that has not yet been released** in a stable version of React. +Bu bölümde, React'in kararlı bir sürümünde henüz yayınlanmamış **deneysel bir API** açıklanmaktadır. -Effect Events let you fix many patterns where you might be tempted to suppress the dependency linter. +Efekt olayları, bağımlılık bağlayıcısını bastırmak isteyebileceğiniz birçok modeli düzeltmenize olanak tanır. -For example, say you have an Effect to log the page visits: +Örneğin, sayfa ziyaretlerini günlüğe kaydetmek için bir Efektiniz olduğunu varsayalım: ```js function Page() { @@ -597,29 +597,29 @@ function Page() { } ``` -Later, you add multiple routes to your site. Now your `Page` component receives a `url` prop with the current path. You want to pass the `url` as a part of your `logVisit` call, but the dependency linter complains: +Daha sonra sitenize birden fazla rota eklersiniz. Şimdi `Page` bileşeniniz geçerli yolu içeren bir `url` prop alır. `url`i `logVisit` çağrınızın bir parçası olarak iletmek istiyorsunuz, ancak bağımlılık linter`ı şikayet ediyor: ```js {1,3} function Page({ url }) { useEffect(() => { logVisit(url); - }, []); // 🔴 React Hook useEffect has a missing dependency: 'url' + }, []); // 🔴 React Hook useEffect'in eksik bir bağımlılığı var: 'url' // ... } ``` -Think about what you want the code to do. You *want* to log a separate visit for different URLs since each URL represents a different page. In other words, this `logVisit` call *should* be reactive with respect to the `url`. This is why, in this case, it makes sense to follow the dependency linter, and add `url` as a dependency: +Kodun ne yapmasını istediğinizi düşünün. Her URL farklı bir sayfayı temsil ettiğinden, farklı URL'ler için ayrı bir ziyareti günlüğe kaydetmek *istiyorsunuz*. Başka bir deyişle, bu `logVisit` çağrısı *`url`ye göre reaktif olmalıdır*. Bu nedenle, bu durumda, bağımlılık linter'ını takip etmek ve `url` öğesini bir bağımlılık olarak eklemek mantıklıdır: ```js {4} function Page({ url }) { useEffect(() => { logVisit(url); - }, [url]); // ✅ All dependencies declared + }, [url]); // ✅ Tüm bagimliliklar bildirildi // ... } ``` -Now let's say you want to include the number of items in the shopping cart together with every page visit: +Şimdi diyelim ki her sayfa ziyaretiyle birlikte alışveriş sepetindeki ürün sayısını da dahil etmek istiyorsunuz: ```js {2-3,6} function Page({ url }) { @@ -628,14 +628,14 @@ function Page({ url }) { useEffect(() => { logVisit(url, numberOfItems); - }, [url]); // 🔴 React Hook useEffect has a missing dependency: 'numberOfItems' + }, [url]); // 🔴 React Hook useEffect'in eksik bir bağımlılığı var: 'numberOfItems' // ... } ``` -You used `numberOfItems` inside the Effect, so the linter asks you to add it as a dependency. However, you *don't* want the `logVisit` call to be reactive with respect to `numberOfItems`. If the user puts something into the shopping cart, and the `numberOfItems` changes, this *does not mean* that the user visited the page again. In other words, *visiting the page* is, in some sense, an "event". It happens at a precise moment in time. +Effect içinde `numberOfItems` kullandınız, bu nedenle linter sizden bunu bir bağımlılık olarak eklemenizi istiyor. Ancak, `logVisit` çağrısının `numberOfItems` ile ilgili olarak reaktif olmasını *istemezsiniz*. Eğer kullanıcı alışveriş sepetine bir şey koyarsa ve `sayıOfItems` değişirse, bu *kullanıcının sayfayı tekrar ziyaret ettiği anlamına gelmez*. Başka bir deyişle, *sayfayı ziyaret etmek* bir anlamda bir "olaydır". Zaman içinde kesin bir anda gerçekleşir. -Split the code in two parts: +Kodu iki parçaya bölün: ```js {5-7,10} function Page({ url }) { @@ -648,20 +648,20 @@ function Page({ url }) { useEffect(() => { onVisit(url); - }, [url]); // ✅ All dependencies declared + }, [url]); // ✅ Tüm bagimliliklar bildirildi // ... } ``` -Here, `onVisit` is an Effect Event. The code inside it isn't reactive. This is why you can use `numberOfItems` (or any other reactive value!) without worrying that it will cause the surrounding code to re-execute on changes. +Burada, `onVisit` bir Efekt olayıdır. İçindeki kod reaktif değildir. Bu nedenle `numberOfItems` (veya başka herhangi bir reaktif değer!) kullanabilir ve bunun çevredeki kodun değişikliklerde yeniden yürütülmesine neden olacağından endişe duymazsınız. -On the other hand, the Effect itself remains reactive. Code inside the Effect uses the `url` prop, so the Effect will re-run after every re-render with a different `url`. This, in turn, will call the `onVisit` Effect Event. +Öte yandan, Efektin kendisi reaktif kalır. Efekt içindeki kod `url` özelliğini kullanır, bu nedenle Efekt her yeniden oluşturmadan sonra farklı bir `url` ile yeniden çalışacaktır. Bu da `onVisit` Efekt olayını çağıracaktır. -As a result, you will call `logVisit` for every change to the `url`, and always read the latest `numberOfItems`. However, if `numberOfItems` changes on its own, this will not cause any of the code to re-run. +Sonuç olarak, `url` öğesindeki her değişiklik için `logVisit` öğesini çağıracak ve her zaman en son `numberOfItems` öğesini okuyacaksınız. Ancak, `numberOfItems` kendi başına değişirse, bu kodun yeniden çalışmasına neden olmaz. -You might be wondering if you could call `onVisit()` with no arguments, and read the `url` inside it: +Hiçbir argüman olmadan `onVisit()` fonksiyonunu çağırıp içindeki `url`yi okuyup okuyamayacağınızı merak ediyor olabilirsiniz: ```js {2,6} const onVisit = useEffectEvent(() => { @@ -673,7 +673,7 @@ You might be wondering if you could call `onVisit()` with no arguments, and read }, [url]); ``` -This would work, but it's better to pass this `url` to the Effect Event explicitly. **By passing `url` as an argument to your Effect Event, you are saying that visiting a page with a different `url` constitutes a separate "event" from the user's perspective.** The `visitedUrl` is a *part* of the "event" that happened: +Bu işe yarayabilir, ancak bu `url`yi Efekt olayına açıkça aktarmak daha iyidir. **Efekt olayınıza bir argüman olarak `url` geçerek, farklı bir `url` ile bir sayfayı ziyaret etmenin kullanıcının bakış açısından ayrı bir "olay" oluşturduğunu söylemiş olursunuz.** `visitedUrl`, gerçekleşen "olayın" bir *parçasıdı*: ```js {1-2,6} const onVisit = useEffectEvent(visitedUrl => { @@ -685,9 +685,9 @@ This would work, but it's better to pass this `url` to the Effect Event explicit }, [url]); ``` -Since your Effect Event explicitly "asks" for the `visitedUrl`, now you can't accidentally remove `url` from the Effect's dependencies. If you remove the `url` dependency (causing distinct page visits to be counted as one), the linter will warn you about it. You want `onVisit` to be reactive with regards to the `url`, so instead of reading the `url` inside (where it wouldn't be reactive), you pass it *from* your Effect. +Efekt olayınızın `visitedUrl` öğesini açıkça "sorduğu" için, artık `url` öğesini Efektin bağımlılıklarından yanlışlıkla kaldıramazsınız. Eğer `url` bağımlılığını kaldırırsanız (farklı sayfa ziyaretlerinin tek bir ziyaret olarak sayılmasına neden olursanız), linter sizi bu konuda uyaracaktır. `onVisit`in `url` ile ilgili olarak reaktif olmasını istersiniz, bu nedenle `url`yi içeriden okumak yerine (reaktif olmayacağı yerde), Efektinizden *geçirirsiniz. -This becomes especially important if there is some asynchronous logic inside the Effect: +Bu, özellikle Efekt içinde bazı asenkron mantık varsa önemli hale gelir: ```js {6,8} const onVisit = useEffectEvent(visitedUrl => { @@ -697,19 +697,19 @@ This becomes especially important if there is some asynchronous logic inside the useEffect(() => { setTimeout(() => { onVisit(url); - }, 5000); // Delay logging visits + }, 5000); // Ziyaretleri kaydetmeyi geciktirin }, [url]); ``` -Here, `url` inside `onVisit` corresponds to the *latest* `url` (which could have already changed), but `visitedUrl` corresponds to the `url` that originally caused this Effect (and this `onVisit` call) to run. +Burada, `onVisit` içindeki `url` *en son* `url`ye karşılık gelir (bu zaten değişmiş olabilir), ancak `visitedUrl` başlangıçta bu Efektin (ve bu `onVisit` çağrısının) çalışmasına neden olan `url`ye karşılık gelir. -#### Is it okay to suppress the dependency linter instead? {/*is-it-okay-to-suppress-the-dependency-linter-instead*/} +#### Bunun yerine bağımlılık linterini bastırmak doğru olur mu? {/*is-it-okay-to-suppress-the-dependency-linter-instead*/} -In the existing codebases, you may sometimes see the lint rule suppressed like this: +Mevcut kod tabanlarında bazen lint kuralının bu şekilde bastırıldığını görebilirsiniz: ```js {7-9} function Page({ url }) { @@ -718,20 +718,20 @@ function Page({ url }) { useEffect(() => { logVisit(url, numberOfItems); - // 🔴 Avoid suppressing the linter like this: + // 🔴 Linteri bu şekilde bastırmaktan kaçının: // eslint-disable-next-line react-hooks/exhaustive-deps }, [url]); // ... } ``` -After `useEffectEvent` becomes a stable part of React, we recommend **never suppressing the linter**. +`UseEffectEvent` React'in kararlı bir parçası haline geldikten sonra, **kuralın asla bastırılmamasını** öneriyoruz. -The first downside of suppressing the rule is that React will no longer warn you when your Effect needs to "react" to a new reactive dependency you've introduced to your code. In the earlier example, you added `url` to the dependencies *because* React reminded you to do it. You will no longer get such reminders for any future edits to that Effect if you disable the linter. This leads to bugs. +Kuralı bastırmanın ilk dezavantajı, Efektinizin kodunuza eklediğiniz yeni bir reaktif bağımlılığa "tepki vermesi" gerektiğinde React'in artık sizi uyarmayacak olmasıdır. Önceki örnekte, React size bunu yapmanızı hatırlattığı için bağımlılıklara `url` eklediniz. Linter'ı devre dışı bırakırsanız, bu Efekt üzerinde gelecekte yapacağınız düzenlemeler için artık böyle hatırlatıcılar almayacaksınız. Bu da hatalara yol açar. -Here is an example of a confusing bug caused by suppressing the linter. In this example, the `handleMove` function is supposed to read the current `canMove` state variable value in order to decide whether the dot should follow the cursor. However, `canMove` is always `true` inside `handleMove`. +Burada, bağlayıcıyı bastırmanın neden olduğu kafa karıştırıcı bir hata örneği verilmiştir. Bu örnekte, `handleMove` fonksiyonunun, noktanın imleci takip edip etmeyeceğine karar vermek için mevcut `canMove` durum değişkeni değerini okuması gerekmektedir. Ancak, `handleMove` içinde `canMove` her zaman `true` değerindedir. -Can you see why? +Nedenini anlayabiliyor musunuz? @@ -761,7 +761,7 @@ export default function App() { checked={canMove} onChange={e => setCanMove(e.target.checked)} /> - The dot is allowed to move + Noktanın hareket etmesine izin verilir
-The problem with this code is in suppressing the dependency linter. If you remove the suppression, you'll see that this Effect should depend on the `handleMove` function. This makes sense: `handleMove` is declared inside the component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time! +Bu kodla ilgili sorun, bağımlılık linterinin bastırılmasıdır. Bastırmayı kaldırırsanız, bu Efektin `handleMove` fonksiyonuna bağlı olması gerektiğini görürsünüz. Bu mantıklıdır: `handleMove` bileşen gövdesi içinde bildirilir, bu da onu reaktif bir değer yapar. Her reaktif değer bir bağımlılık olarak belirtilmelidir, aksi takdirde zaman içinde eskimesi olasıdır! -The author of the original code has "lied" to React by saying that the Effect does not depend (`[]`) on any reactive values. This is why React did not re-synchronize the Effect after `canMove` has changed (and `handleMove` with it). Because React did not re-synchronize the Effect, the `handleMove` attached as a listener is the `handleMove` function created during the initial render. During the initial render, `canMove` was `true`, which is why `handleMove` from the initial render will forever see that value. +Orijinal kodun yazarı, Effect'in herhangi bir reaktif değere bağlı olmadığını (`[]`) söyleyerek React'e "yalan söylemiştir". Bu nedenle React, `canMove` değiştikten sonra (ve onunla birlikte `handleMove`) Efekti yeniden senkronize etmedi. React, Efekti yeniden senkronize etmediği için, dinleyici olarak eklenen `handleMove`, ilk render sırasında oluşturulan `handleMove` fonksiyonudur. İlk render sırasında `canMove` `true` idi, bu yüzden ilk renderdan `handleMove` sonsuza kadar bu değeri görecektir. -**If you never suppress the linter, you will never see problems with stale values.** +**Linter'ı asla bastırmazsanız, eski değerlerle ilgili sorunları asla görmezsiniz.** -With `useEffectEvent`, there is no need to "lie" to the linter, and the code works as you would expect: +`UseEffectEvent` ile linter`a "yalan söylemeye" gerek yoktur ve kod beklediğiniz gibi çalışır: @@ -842,7 +842,7 @@ export default function App() { checked={canMove} onChange={e => setCanMove(e.target.checked)} /> - The dot is allowed to move + Noktanın hareket etmesine izin verilir
-This doesn't mean that `useEffectEvent` is *always* the correct solution. You should only apply it to the lines of code that you don't want to be reactive. In the above sandbox, you didn't want the Effect's code to be reactive with regards to `canMove`. That's why it made sense to extract an Effect Event. +Bu, `useEffectEvent`in *her zaman* doğru çözüm olduğu anlamına gelmez. Bunu yalnızca reaktif olmasını istemediğiniz kod satırlarına uygulamalısınız. Yukarıdaki sanal alanda, Efekt kodunun `canMove` ile ilgili olarak reaktif olmasını istemediniz. Bu yüzden bir Efekt olayı çıkarmak mantıklı oldu. -Read [Removing Effect Dependencies](/learn/removing-effect-dependencies) for other correct alternatives to suppressing the linter. +Linteri bastırmanın diğer doğru alternatifleri için [Efekt Bağımlılıklarını Kaldırma](/learn/removing-effect-dependencies) bölümünü okuyun. -### Limitations of Effect Events {/*limitations-of-effect-events*/} +### Efekt Olaylarının Sınırlamaları {/*limitations-of-effect-events*/} -This section describes an **experimental API that has not yet been released** in a stable version of React. +Bu bölümde, React'in kararlı bir sürümünde henüz yayınlanmamış **deneysel bir API** açıklanmaktadır. -Effect Events are very limited in how you can use them: +Efekt Olayları, kullanma şekliniz açısından oldukça sınırlıdır: -* **Only call them from inside Effects.** -* **Never pass them to other components or Hooks.** +* **Sadece Efektlerin içinden çağırın.** +* **Asla diğer bileşenlere veya Hook'lara aktarmayın.** -For example, don't declare and pass an Effect Event like this: +Örneğin, bir Efekt olayını şu şekilde bildirmeyin ve geçirmeyin: ```js {4-6,8} function Timer() { @@ -899,7 +899,7 @@ function Timer() { setCount(count + 1); }); - useTimer(onTick, 1000); // 🔴 Avoid: Passing Effect Events + useTimer(onTick, 1000); // 🔴 Kaçının: Efekt olaylarini geçmek return

{count}

} @@ -912,11 +912,11 @@ function useTimer(callback, delay) { return () => { clearInterval(id); }; - }, [delay, callback]); // Need to specify "callback" in dependencies + }, [delay, callback]); // Bağımlılıklarda "callback" fonksiyonunu belirtmeniz gerekiyor } ``` -Instead, always declare Effect Events directly next to the Effects that use them: +Bunun yerine, her zaman Efekt olaylarını doğrudan onları kullanan Efektlerin yanında bildirin: ```js {10-12,16,21} function Timer() { @@ -934,40 +934,40 @@ function useTimer(callback, delay) { useEffect(() => { const id = setInterval(() => { - onTick(); // ✅ Good: Only called locally inside an Effect + onTick(); // ✅ İyi: Yalnızca bir Efektin içinde yerel olarak çağrılır }, delay); return () => { clearInterval(id); }; - }, [delay]); // No need to specify "onTick" (an Effect Event) as a dependency + }, [delay]); // Bağımlılık olarak "onTick" (bir Efekt olayı) belirtmeye gerek yok } ``` -Effect Events are non-reactive "pieces" of your Effect code. They should be next to the Effect using them. +Efekt olayları, Efekt kodunuzun reaktif olmayan "parçalarıdır". Kendilerini kullanan Efektin yanında olmalıdırlar. -- Event handlers run in response to specific interactions. -- Effects run whenever synchronization is needed. -- Logic inside event handlers is not reactive. -- Logic inside Effects is reactive. -- You can move non-reactive logic from Effects into Effect Events. -- Only call Effect Events from inside Effects. -- Don't pass Effect Events to other components or Hooks. +- Olay yöneticileri belirli etkileşimlere yanıt olarak çalışır. +- Efektler, senkronizasyon gerektiğinde çalışır. +- Olay yöneticilerinin içindeki mantık reaktif değildir. +- Efektlerin içindeki mantık reaktiftir. +- Reaktif olmayan mantığı Efektlerden Efekt olaylarına taşıyabilirsiniz. +- Efekt olaylarını yalnızca Efektlerin içinden çağırın. +- Efekt olaylarını diğer bileşenlere veya Hook'lara aktarmayın. -#### Fix a variable that doesn't update {/*fix-a-variable-that-doesnt-update*/} +#### Güncellenmeyen bir değişkeni düzeltme {/*fix-a-variable-that-doesnt-update*/} -This `Timer` component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable. You can control the `increment` variable with the plus and minus buttons. +Bu `Timer` bileşeni her saniye artan bir `count` durum değişkenini tutar. Artan değer `increment` durum değişkeninde saklanır. Artı ve eksi düğmeleriyle `increment` değişkenini kontrol edebilirsiniz. -However, no matter how many times you click the plus button, the counter is still incremented by one every second. What's wrong with this code? Why is `increment` always equal to `1` inside the Effect's code? Find the mistake and fix it. +Ancak, artı düğmesine kaç kez tıklarsanız tıklayın, sayaç yine de her saniye bir artar. Bu kodda yanlış olan nedir? Efektin kodu içinde `increment` neden her zaman `1`e eşittir? Hatayı bulun ve düzeltin. -To fix this code, it's enough to follow the rules. +Bu kodu düzeltmek için kurallara uymak yeterlidir. @@ -993,12 +993,12 @@ export default function Timer() { return ( <>

- Counter: {count} + Sayaç: {count}


- Every second, increment by: + Saniyedeki artış miktari: @@ -1020,9 +1020,9 @@ button { margin: 10px; } -As usual, when you're looking for bugs in Effects, start by searching for linter suppressions. +Her zamanki gibi, Efektlerde hata ararken, linter bastırmalarını arayarak başlayın. -If you remove the suppression comment, React will tell you that this Effect's code depends on `increment`, but you "lied" to React by claiming that this Effect does not depend on any reactive values (`[]`). Add `increment` to the dependency array: +Suppression yorumunu kaldırırsanız, React size bu Efektin kodunun `increment` değerine bağlı olduğunu söyleyecektir, ancak siz bu Efektin herhangi bir reaktif değere (`[]`) bağlı olmadığını iddia ederek React'e "yalan söylediniz". Bağımlılık dizisine `increment` ekleyin: @@ -1045,12 +1045,12 @@ export default function Timer() { return ( <>

- Counter: {count} + Sayaç: {count}


- Every second, increment by: + Saniyedeki artış miktari: @@ -1070,19 +1070,19 @@ button { margin: 10px; } -Now, when `increment` changes, React will re-synchronize your Effect, which will restart the interval. +Şimdi, `increment` değiştiğinde, React Efektinizi yeniden senkronize edecek ve bu da aralığı yeniden başlatacakır. -#### Fix a freezing counter {/*fix-a-freezing-counter*/} +#### Donan bir sayacı düzeltin {/*fix-a-freezing-counter*/} -This `Timer` component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable, which you can control it with the plus and minus buttons. For example, try pressing the plus button nine times, and notice that the `count` now increases each second by ten rather than by one. +Bu `Timer` bileşeni her saniye artan bir `count` durum değişkenini tutar. Artan değer `increment` durum değişkeninde saklanır ve bunu artı ve eksi düğmeleriyle kontrol edebilirsiniz. Örneğin, artı düğmesine dokuz kez basmayı deneyin ve `sayı`nın artık her saniye bir yerine on arttığına dikkat edin. -There is a small issue with this user interface. You might notice that if you keep pressing the plus or minus buttons faster than once per second, the timer itself seems to pause. It only resumes after a second passes since the last time you've pressed either button. Find why this is happening, and fix the issue so that the timer ticks on *every* second without interruptions. +Bu kullanıcı arayüzü ile ilgili küçük bir sorun var. Artı veya eksi düğmelerine saniyede bir kereden daha hızlı basmaya devam ederseniz, zamanlayıcının kendisinin durakladığını fark edebilirsiniz. Ancak düğmelerden birine son basışınızın üzerinden bir saniye geçtikten sonra devam eder. Bunun neden olduğunu bulun ve sorunu çözerek zamanlayıcının kesintisiz olarak *her* saniye çalışmasını sağlayın. -It seems like the Effect which sets up the timer "reacts" to the `increment` value. Does the line that uses the current `increment` value in order to call `setCount` really need to be reactive? +Görünüşe göre zamanlayıcıyı kuran Efekt `increment` değerine "tepki" veriyor. `setCount`u çağırmak için mevcut `increment` değerini kullanan satırın gerçekten reaktif olması gerekiyor mu? @@ -1124,12 +1124,12 @@ export default function Timer() { return ( <>

- Counter: {count} + Sayaç: {count}


- Every second, increment by: + Saniyedeki artış miktari: @@ -1151,9 +1151,9 @@ button { margin: 10px; } -The issue is that the code inside the Effect uses the `increment` state variable. Since it's a dependency of your Effect, every change to `increment` causes the Effect to re-synchronize, which causes the interval to clear. If you keep clearing the interval every time before it has a chance to fire, it will appear as if the timer has stalled. +Sorun, Efekt içindeki kodun `increment` state değişkenini kullanmasıdır. Bu, Efektinizin bir bağımlılığı olduğundan, `increment` durumundaki her değişiklik Efektin yeniden senkronize olmasına neden olur ve bu da aralığın temizlenmesine neden olur. Ateşleme şansı bulmadan önce her seferinde aralığı temizlemeye devam ederseniz, zamanlayıcı durmuş gibi görünecektir. -To solve the issue, extract an `onTick` Effect Event from the Effect: +Sorunu çözmek için, Efektten bir `onTick` Efekt olayı çıkarın: @@ -1197,12 +1197,12 @@ export default function Timer() { return ( <>

- Counter: {count} + Sayaç: {count}


- Every second, increment by: + Saniyedeki artış miktari: @@ -1223,17 +1223,17 @@ button { margin: 10px; } -Since `onTick` is an Effect Event, the code inside it isn't reactive. The change to `increment` does not trigger any Effects. +`onTick` bir Efekt olayı olduğundan, içindeki kod reaktif değildir. Increment` değişikliği herhangi bir Efekti tetiklemez. -#### Fix a non-adjustable delay {/*fix-a-non-adjustable-delay*/} +#### Ayarlanamayan bir gecikmeyi düzeltin {/*fix-a-non-adjustable-delay*/} -In this example, you can customize the interval delay. It's stored in a `delay` state variable which is updated by two buttons. However, even if you press the "plus 100 ms" button until the `delay` is 1000 milliseconds (that is, a second), you'll notice that the timer still increments very fast (every 100 ms). It's as if your changes to the `delay` are ignored. Find and fix the bug. +Bu örnekte, aralık gecikmesini özelleştirebilirsiniz. Bu, iki düğme tarafından güncellenen bir `delay` state değişkeninde saklanır. Ancak, `delay` 1000 milisaniye (yani bir saniye) olana kadar "artı 100 ms" düğmesine bassanız bile, zamanlayıcının hala çok hızlı (her 100 ms'de bir) arttığını fark edeceksiniz. Sanki `delay`'de yaptığınız değişiklikler göz ardı edilmiş gibi. Hatayı bulun ve düzeltin. -Code inside Effect Events is not reactive. Are there cases in which you would _want_ the `setInterval` call to re-run? +Effect olayları içindeki kod reaktif değildir. `setInterval` çağrısının yeniden çalışmasını _istediğiniz_ durumlar var mı? @@ -1284,12 +1284,12 @@ export default function Timer() { return ( <>

- Counter: {count} + Sayaç: {count}


- Increment by: + Artış: @@ -1299,7 +1299,7 @@ export default function Timer() { }}>+

- Increment delay: + Artış gecikmesi: @@ -1322,7 +1322,7 @@ button { margin: 10px; } -The problem with the above example is that it extracted an Effect Event called `onMount` without considering what the code should actually be doing. You should only extract Effect Events for a specific reason: when you want to make a part of your code non-reactive. However, the `setInterval` call *should* be reactive with respect to the `delay` state variable. If the `delay` changes, you want to set up the interval from scratch! To fix this code, pull all the reactive code back inside the Effect: +Yukarıdaki örnekle ilgili sorun, kodun gerçekte ne yapması gerektiğini düşünmeden `onMount` adlı bir Effect Event çıkarmasıdır. Efekt olaylarını yalnızca belirli bir nedenle çıkarmalısınız: kodunuzun bir bölümünü reaktif olmayan hale getirmek istediğinizde. Bununla birlikte, `setInterval` çağrısı `delay` durum değişkenine göre reaktif olmalıdır. Eğer `delay` değişirse, aralığı sıfırdan ayarlamak istersiniz! Bu kodu düzeltmek için, tüm reaktif kodu Efektin içine geri çekin: @@ -1367,12 +1367,12 @@ export default function Timer() { return ( <>

- Counter: {count} + Sayaç: {count}


- Increment by: + Artış: @@ -1382,7 +1382,7 @@ export default function Timer() { }}>+

- Increment delay: + Artış gecikmesi: @@ -1402,21 +1402,21 @@ button { margin: 10px; } -In general, you should be suspicious of functions like `onMount` that focus on the *timing* rather than the *purpose* of a piece of code. It may feel "more descriptive" at first but it obscures your intent. As a rule of thumb, Effect Events should correspond to something that happens from the *user's* perspective. For example, `onMessage`, `onTick`, `onVisit`, or `onConnected` are good Effect Event names. Code inside them would likely not need to be reactive. On the other hand, `onMount`, `onUpdate`, `onUnmount`, or `onAfterRender` are so generic that it's easy to accidentally put code that *should* be reactive into them. This is why you should name your Effect Events after *what the user thinks has happened,* not when some code happened to run. +Genel olarak, bir kod parçasının *amacından* ziyade *zamanlamasına* odaklanan `onMount` gibi fonksiyonlara şüpheyle yaklaşmalısınız. İlk başta "daha açıklayıcı" gelebilir ancak amacınızı gizler. Genel bir kural olarak, Efekt olayları *kullanıcının* bakış açısından gerçekleşen bir şeye karşılık gelmelidir. Örneğin, `onMessage`, `onTick`, `onVisit` veya `onConnected` iyi Effect olay adlarıdır. İçlerindeki kodun muhtemelen reaktif olması gerekmeyecektir. Öte yandan, `onMount`, `onUpdate`, `onUnmount` veya `onAfterRender` o kadar geneldir ki, yanlışlıkla * reaktif olması gereken * kodları bunlara koymak kolaydır. Bu nedenle, Efekt olaylarınızı bazı kodların ne zaman çalıştığına göre değil, *kullanıcının ne olduğunu düşündüğüne göre* adlandırmalısınız. -#### Fix a delayed notification {/*fix-a-delayed-notification*/} +#### Geciken bir bildirimi düzeltme {/*fix-a-delayed-notification*/} -When you join a chat room, this component shows a notification. However, it doesn't show the notification immediately. Instead, the notification is artificially delayed by two seconds so that the user has a chance to look around the UI. +Bir sohbet odasına katıldığınızda, bu bileşen bir bildirim gösterir. Ancak, bildirimi hemen göstermez. Bunun yerine, bildirim yapay olarak iki saniye geciktirilir, böylece kullanıcının kullanıcı arayüzüne bakma şansı olur. -This almost works, but there is a bug. Try changing the dropdown from "general" to "travel" and then to "music" very quickly. If you do it fast enough, you will see two notifications (as expected!) but they will *both* say "Welcome to music". +Bu neredeyse işe yarıyor, ancak bir hata var. Açılır menüyü "genel "den "seyahat "e ve ardından çok hızlı bir şekilde "müzik "e değiştirmeyi deneyin. Bunu yeterince hızlı yaparsanız, iki bildirim göreceksiniz (beklendiği gibi!) ancak her ikisinde de * "Müziğe hoş geldiniz" yazacaktır. -Fix it so that when you switch from "general" to "travel" and then to "music" very quickly, you see two notifications, the first one being "Welcome to travel" and the second one being "Welcome to music". (For an additional challenge, assuming you've *already* made the notifications show the correct rooms, change the code so that only the latter notification is displayed.) +"Genel"den "seyahat"e ve ardından çok hızlı bir şekilde "müzik"e geçtiğinizde, ilki "Seyahate hoş geldiniz" ve ikincisi "Müziğe hoş geldiniz" olmak üzere iki bildirim görecek şekilde düzeltin. (Ek bir zorluk için, *zaten* bildirimlerin doğru odaları göstermesini sağladığınızı varsayarak, kodu yalnızca ikinci bildirim görüntülenecek şekilde değiştirin). -Your Effect knows which room it connected to. Is there any information that you might want to pass to your Effect Event? +Efektiniz hangi odaya bağlı olduğunu bilir. Efekt Olayınıza aktarmak isteyebileceğiniz herhangi bir bilgi var mı? @@ -1467,19 +1467,19 @@ function ChatRoom({ roomId, theme }) { } export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('genel'); const [isDark, setIsDark] = useState(false); return ( <>


-Inside your Effect Event, `roomId` is the value *at the time Effect Event was called.* +Efekt olayınızın içinde, `roomId` değeri *Efekt olayının çağrıldığı andaki değerdir.* -Your Effect Event is called with a two second delay. If you're quickly switching from the travel to the music room, by the time the travel room's notification shows, `roomId` is already `"music"`. This is why both notifications say "Welcome to music". +Efekt olayınıza iki saniyelik bir gecikmeyle çağrılır. Seyahat odasından müzik odasına hızlı bir şekilde geçiş yapıyorsanız, seyahat odasının bildirimi gösterildiğinde, `roomId` zaten `"müzik"`tir. Bu yüzden her iki bildirimde de "Müziğe hoş geldiniz" yazıyor. -To fix the issue, instead of reading the *latest* `roomId` inside the Effect Event, make it a parameter of your Effect Event, like `connectedRoomId` below. Then pass `roomId` from your Effect by calling `onConnected(roomId)`: +Sorunu çözmek için, Efekt olayı içinde *en son* `roomId`yi okumak yerine, aşağıdaki `connectedRoomId` gibi Efekt olayınızın bir parametresi haline getirin. Ardından `onConnected(roomId)` çağrısı yaparak `roomId`yi Efektinizden geçirin: @@ -1604,23 +1604,23 @@ function ChatRoom({ roomId, theme }) { return () => connection.disconnect(); }, [roomId]); - return

Welcome to the {roomId} room!

+ return

{roomId} odasına hoş geldiniz!

} export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('genel'); const [isDark, setIsDark] = useState(false); return ( <>
-The Effect that had `roomId` set to `"travel"` (so it connected to the `"travel"` room) will show the notification for `"travel"`. The Effect that had `roomId` set to `"music"` (so it connected to the `"music"` room) will show the notification for `"music"`. In other words, `connectedRoomId` comes from your Effect (which is reactive), while `theme` always uses the latest value. +`roomId`nin `"seyahat"` olarak ayarlandığı (yani `"seyahat"` odasına bağlandığı) Efekt, `"seyahat"` için bildirim gösterecektir. `roomId` değeri `"müzik"` olarak ayarlanmış olan (yani `"müzik"` odasına bağlanmış olan) Efekt, `"müzik"` için bildirim gösterecektir. Başka bir deyişle, `connectedRoomId` Efektinizden (reaktif olan) gelirken, `theme` her zaman en son değeri kullanır. -To solve the additional challenge, save the notification timeout ID and clear it in the cleanup function of your Effect: +Ek zorluğu çözmek için, bildirim zaman aşımı kimliğini kaydedin ve Efektinizin temizleme işlevinde temizleyin: @@ -1747,23 +1747,23 @@ function ChatRoom({ roomId, theme }) { }; }, [roomId]); - return

Welcome to the {roomId} room!

+ return

{roomId} odasına hoş geldiniz!

} export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('genel'); const [isDark, setIsDark] = useState(false); return ( <>
-This ensures that already scheduled (but not yet displayed) notifications get cancelled when you change rooms. + +Bu, oda değiştirdiğinizde önceden planlanmış (ancak henüz görüntülenmemiş) bildirimlerin iptal edilmesini sağlar. + -
+ \ No newline at end of file