swr
swr copied to clipboard
Add `isMutated` boolean to track local mutations
Bug report
Description / Observed Behavior
SWR sometimes accidentally revalidates locally mutated data (i.e. data that has been mutated locally without revalidation but isn't yet saved in our database which causes undesired state wipes when SWR revalidates after an e.g. switched tab).
Expected Behavior
SWR should keep track of local mutations per key and then return a boolean value isMutated
that indicates:
-
true
- The currentdata
was the result of a local mutation that wasn't actually fetched from the back-end. -
false
- The currentdata
is the response from afetch
request.
Repro Steps / Code Example
For example:
const { data, isMutated, isValidating, mutate } = useSWR('/api/account');
// 1) data = undefined, isMutated = false, isValidating = true
// 2) data is fetched from `/api/account` successfully
// 3) data = serverAccount, isMutated = false, isValidating = false
await mutate(updatedAccount, false);
// 4) data = updatedAccount, isMutated = true, isValidating = false
await mutate(updatedAccount, true);
// 5) data = updatedAccount, isMutated = true, isValidating = true
// 6) revalidation from `/api/account` occurs successfully
// 7) data = serverAccount, isMutated = false, isValidating = false
Additional Context
SWR version: 0.5.6
Add any other context about the problem here.
I have an infinite scrolling UI that determines whether or not there is more data to load by the length of the last server response (for /api/messages
). Each full "page" of data contains 5 messages. Thus, I know that there's no more data to load if the last server response has a length of less than (<) 5 messages. However, if the user locally mutates that last page data and changes its length (e.g. to archive a message which removes it from the feed), I can no longer rely on it to determine if there's more data to be loaded. If I had this isMutated
boolean value, however, I could simply have an OR statement:
hasMore={isMutated || data[data.length - 1].length === 5} // The infinite scroller has more messages to show.