Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/content/learn/you-might-not-need-an-effect.md
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,8 @@ This might seem like a contradiction with the earlier examples where you needed

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.

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.

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.

**To fix the race condition, you need to [add a cleanup function](/learn/synchronizing-with-effects#fetching-data) to ignore stale responses:**
Expand Down
Loading