Skip to content

Commit c8760b6

Browse files
claudedeepusnath
authored andcommitted
Clarify why fetching stays in the Effect in "Fetching data"
The "Fetching data" example keeps `page` in the Effect's dependency array while also updating it from `handleNextPageClick`, which reads as a contradiction with the page's own advice to prefer event handlers. Add a paragraph making the deciding factor explicit: fetch in the handler when a value can *only* change from that event, and synchronize in an Effect when the value can also change for other reasons (here, `page` and `query` can both come from the URL via Back/Forward). Addresses #8506 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SkNCfa3G9cdgYoYGefCbYm
1 parent 9e97ad0 commit c8760b6

1 file changed

Lines changed: 2 additions & 0 deletions

File tree

src/content/learn/you-might-not-need-an-effect.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,8 @@ This might seem like a contradiction with the earlier examples where you needed
726726
727727
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.
728728
729+
This distinction matters when deciding whether to fetch inside the Effect or the event handler. If `page` could *only* ever change from `handleNextPageClick`, you could fetch directly inside that handler and drop `page` from the Effect's dependencies entirely. But `page` isn't only set by that click—like `query`, it could also come from the URL, so that Back and Forward navigation show the right results without the user touching anything. Whenever a value can change for reasons other than the event you're handling, synchronizing off of it in an Effect (rather than fetching ad hoc from every place that can change it) is what keeps `results` correct no matter which of those reasons caused the change.
730+
729731
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.
730732
731733
**To fix the race condition, you need to [add a cleanup function](/learn/synchronizing-with-effects#fetching-data) to ignore stale responses:**

0 commit comments

Comments
 (0)