Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stale data when mutating key with no registered updaters #751

Closed
muqg opened this issue Nov 6, 2020 · 4 comments
Closed

Stale data when mutating key with no registered updaters #751

muqg opened this issue Nov 6, 2020 · 4 comments

Comments

@muqg
Copy link

muqg commented Nov 6, 2020

Bug report

Description / Observed Behavior

I have a list of items and a page for each item like so:

function Item() {
  const item = useSWR(URL_TO_ITEM)
  // ...
}

function ItemList() {
  const items = useSWR(URL_TO_ITEM_LIST)
  // ...
}

While the <Item /> component is rendered, the <ItemList /> component is not redered and vice versa. The <Item /> component has fields allowing users to modify it and these changes should be reflected in the list. Therefore the update function looks something like this:

async function updateItem(data) {
  const response = await request(URL_TO_ITEM, data)
  mutate(URL_TO_ITEM)
  mutate(URL_TO_ITEM_LIST)

  return response
}

When this function is called a request to revalidate the item data is sent to URL_TO_ITEM and no request is sent to URL_TO_ITEM_LIST since the <ItemList /> component is not rendered and useSWR finds no updaters, which is expected. Now if we navigate to show the <ItemList /> still no request to URL_TO_ITEM_LIST will be sent, rendering it with its previous (stale) data as if no mutate(URL_TO_ITEM_LIST) call was made in the update function at all.

Expected Behavior

Calling mutate() as described above should evict the data under the given key from cache when there are no updaters (no components using it), so that it does not remain stale.

Repro Steps / Code Example

I am currently not able to create a repro case since I am a little bit overwhelmed irl. If the description above is not clear enough, please let me know and I will provide a repro case ASAP.

However I took a quick look at the source code and it seems to me that when the this condition results to false and else case should probably remove the stale data from cache. This will make it so that the next time <ItemList /> is rendered it will find no cached data available and will correctly fetch new data from server. I could be completely wrong though.

Additional Context

SWR version: 0.3.8

// SWRConfig context
{
  fetcher: (url) => axios.get(url).then(res => res.data),
  revalidateOnMount: false,
  revalidateOnFocus: false,
  revalidateOnReconnect: false,
  suspense: true,
}
@promer94
Copy link
Collaborator

promer94 commented Nov 8, 2020

you can do

async function updateItem(data) {
  const response = await request(URL_TO_ITEM, data)
  mutate(URL_TO_ITEM)
  const list = await request(URL_TO_ITEM_LIST)
  mutate(URL_TO_ITEM_LIST, list)
  return response
}

@muqg
Copy link
Author

muqg commented Nov 8, 2020

Sure, that would work. But then again, what kind of signal does a mutate() send in this case?

  1. If I have a mounted component with useSWR(URL_TO_ITEM_LIST) a request will be sent to revalidate the cache.
  2. If there are no mounted components, no request will be sent and the cache would remain stale regardless of my desire to revalidate.

It seems that calling mutate() sometimes revalidates, and sometimes it does not.

If that's intended then perhaps we need an explicit invalidate() function? SWR already knows how to fetch the data and it seems quite unnecessary to manually fetch it just to put it into cache when this can already be done by the library itself.

@nataliemarleny
Copy link

I think this issue is fixed by: #1498

@shuding
Copy link
Member

shuding commented Oct 20, 2021

Yeah I think so, thanks @nataliemarleny!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants