From 55a265c8abc36ec1e781dd244adc8967789289cf Mon Sep 17 00:00:00 2001 From: Kanika Date: Tue, 13 Jan 2026 18:21:47 +0530 Subject: [PATCH 1/3] Clarify when Effects are needed for data fetching Improve the explanation in the 'Fetching data' section to clearly distinguish when an Effect is needed (synchronization with external system) versus when it's not needed (user events, data transformation). Closes #8226 --- src/content/learn/you-might-not-need-an-effect.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/learn/you-might-not-need-an-effect.md b/src/content/learn/you-might-not-need-an-effect.md index 81a0842eb60..4008f24c8cf 100644 --- a/src/content/learn/you-might-not-need-an-effect.md +++ b/src/content/learn/you-might-not-need-an-effect.md @@ -720,11 +720,11 @@ function SearchResults({ query }) { } ``` -You *don't* need to move this fetch to an event handler. +This is a case where an Effect *is* needed because you're [synchronizing](/learn/synchronizing-with-effects) with an external system (the network). However, this is different from the earlier examples where Effects weren't needed. -This might seem like a contradiction with the earlier examples where you needed to put the logic into the event handlers! However, consider that it's not *the typing event* that's the main reason to fetch. Search inputs are often prepopulated from the URL, and the user might navigate Back and Forward without touching the input. +The key difference: here, you need to fetch data whenever `query` or `page` changes, regardless of *how* they changed. The `query` might come from the URL (when the user navigates Back/Forward), or it might be typed by the user. The `page` might change from a button click or from restoring scroll position. It doesn't matter where `page` and `query` come from—while this component is visible, you want to keep `results` synchronized with data from the network for the current `page` and `query`. This is why it's an Effect. -It doesn't matter where `page` and `query` come from. While this component is visible, you want to keep `results` [synchronized](/learn/synchronizing-with-effects) with data from the network for the current `page` and `query`. This is why it's an Effect. +In contrast, if fetching was only needed in response to a specific user action (like clicking a "Search" button), you would put it in that event handler instead. However, the code above has a bug. Imagine you type `"hello"` fast. Then the `query` will change from `"h"`, to `"he"`, `"hel"`, `"hell"`, and `"hello"`. This will kick off separate fetches, but there is no guarantee about which order the responses will arrive in. For example, the `"hell"` response may arrive *after* the `"hello"` response. Since it will call `setResults()` last, you will be displaying the wrong search results. This is called a ["race condition"](https://en.wikipedia.org/wiki/Race_condition): two different requests "raced" against each other and came in a different order than you expected. From ba6729fa0a156bfa1f6b69c2806fd0f674df6b53 Mon Sep 17 00:00:00 2001 From: Kanika Date: Sat, 17 Jan 2026 20:03:40 +0530 Subject: [PATCH 2/3] Fix reversed blog navigation links Swap prevRoute and nextRoute for blog posts to fix navigation direction. Blog posts are ordered newest to oldest, so the traversal order is reversed from chronological order. - Previous link now correctly points to older posts - Next link now correctly points to newer posts This only affects blog posts, other sections remain unchanged. Fixes #7844 --- src/components/Layout/Page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Layout/Page.tsx b/src/components/Layout/Page.tsx index aa39fe5fc2b..b75cca590cf 100644 --- a/src/components/Layout/Page.tsx +++ b/src/components/Layout/Page.tsx @@ -96,8 +96,8 @@ export function Page({ {!isBlogIndex && ( )} From f823b312357e6c2e78b80b9452a9e9c1c3f3d132 Mon Sep 17 00:00:00 2001 From: Kanika Date: Sat, 17 Jan 2026 23:19:29 +0530 Subject: [PATCH 3/3] Add comment explaining blog route swap Add one-line comment explaining why next/prev routes are swapped for blog posts (they're ordered newest to oldest). --- src/components/Layout/Page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Layout/Page.tsx b/src/components/Layout/Page.tsx index b75cca590cf..d64a5aa1cee 100644 --- a/src/components/Layout/Page.tsx +++ b/src/components/Layout/Page.tsx @@ -96,6 +96,7 @@ export function Page({ {!isBlogIndex && (