From d21d5194bcf3767005ee199cae2968b498b0469e Mon Sep 17 00:00:00 2001 From: Burak Cihan Date: Mon, 11 Sep 2023 22:02:14 +0300 Subject: [PATCH 01/10] feat: translate to page --- .gitignore | 3 + .../learn/separating-events-from-effects.md | 73 +++++++++---------- 2 files changed, 39 insertions(+), 37 deletions(-) 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..0c9f9fcb2 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -1,37 +1,36 @@ --- -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 işleyicileri yalnızca aynı etkileşimi tekrar gerçekleştirdiğinizde yeniden çalışır. Olay işleyicilerin 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 işleyici ile bir Efekt arasında nasıl seçim yapılır? +- Efektler neden reaktiftir ve olay işleyicileri 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 işleyicileri 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 işleyicileri ve Efektler arasındaki farkı özetleyelim. -Imagine you're implementing a chat room component. Your requirements look like this: +Bir sohbet odası bileşeni uyguladığınızı 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 işleyicileri 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 işleyicileri 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 işleyici olmalıdır. Olay işleyicileri belirli etkileşimleri ele almanızı sağlar: ```js {4-6} function ChatRoom({ roomId }) { @@ -44,19 +43,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 işleyicisi 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 +71,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 +96,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 && } @@ -136,13 +135,13 @@ export function sendMessage(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('✅ Bağlanmak "' + roomId + '" oda ' + serverUrl + '...'); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ Bağlantısı kesildi "' + roomId + '" oda ' + serverUrl); } }; } @@ -154,13 +153,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 işleyicilerinin 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'; From bc332086a3c605be482f97c649733a1f1e72a717 Mon Sep 17 00:00:00 2001 From: Burak Cihan Date: Mon, 11 Sep 2023 22:04:30 +0300 Subject: [PATCH 02/10] feat: translate to page --- src/content/learn/separating-events-from-effects.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index 0c9f9fcb2..75a604483 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -171,16 +171,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ı `mesaj`ı düzenleyebilir veya bir açılır menüde farklı bir `odaId` seçebilir. Olay işleyicileri 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 işleyicilerinin 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 işleyicileri, 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 işleyicileri 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"]] // ... From b729eb0129ec1357db7365912255846910df4195 Mon Sep 17 00:00:00 2001 From: Burak Cihan Date: Tue, 12 Sep 2023 00:54:51 +0300 Subject: [PATCH 03/10] feat: transtlate to page --- .../learn/separating-events-from-effects.md | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index 75a604483..1619eb374 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -188,7 +188,7 @@ Bu farkı göstermek için bir önceki örneğe geri dönelim. // ... ``` -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, **`mesaj`'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 işleyicisine aittir: ```js {2} function handleSendClick() { @@ -196,11 +196,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 işleyicileri 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"]] // ... @@ -209,7 +209,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 Etkiye aittir: ```js {2-3} useEffect(() => { @@ -221,13 +221,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ığı Effects'ten çı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 }) { @@ -240,24 +240,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ğlı!', theme); }); connection.connect(); return () => { connection.disconnect() }; - }, [roomId, theme]); // ✅ All dependencies declared + }, [roomId, theme]); // ✅ Bildirilen tüm bağımlılıklar // ... ``` -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: @@ -289,29 +289,29 @@ function ChatRoom({ roomId, theme }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.on('connected', () => { - showNotification('Connected!', theme); + showNotification('Bağlı!', 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ğlı!', 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 Etki 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 Kanca kullanın: ```js {1,4-6} import { useEffect, useEffectEvent } from 'react'; function ChatRoom({ roomId, theme }) { const onConnected = useEffectEvent(() => { - showNotification('Connected!', theme); + showNotification('Bağlı!', 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 işleyici 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('Bağlı!', theme); }); useEffect(() => { @@ -434,13 +434,13 @@ function ChatRoom({ roomId, theme }) { }); connection.connect(); return () => connection.disconnect(); - }, [roomId]); // ✅ All dependencies declared + }, [roomId]); // ✅ Bildirilen tüm bağımlılıklar // ... ``` -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: @@ -471,7 +471,7 @@ const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId, theme }) { const onConnected = useEffectEvent(() => { - showNotification('Connected!', theme); + showNotification('Bağlı!', theme); }); useEffect(() => { @@ -483,11 +483,11 @@ 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 ( <> @@ -497,9 +497,9 @@ export default function App() { value={roomId} onChange={e => setRoomId(e.target.value)} > - - - + + +