swr icon indicating copy to clipboard operation
swr copied to clipboard

Mutate's async function data is set to `undefined` with `getServerSideProps` and no revalidation

Open tonypizzicato opened this issue 1 year ago • 4 comments

Bug report

Description / Observed Behavior

Mutate Based on Current Data Docs mutate's async function data is set to undefined when used with Next.js getServerSideProps fallback and revalidateIfStale: false even though the fallback works fine and data from the server is rendered right away.

Expected Behavior

mutate async callback has data from the server w/o refetching on the client

Repro Steps / Code Example

CodeSandbox

Click do mutate button. Check that local items output is undefined Go to About page and back to Home page. Click do mutate button: local items output is updated as swr data was updated on the client. Setting revalidateIfStale to true fixes the issue as the data being refetched on the client.

Additional Context

SWR version 2.1.1

tonypizzicato avatar Apr 04 '23 20:04 tonypizzicato

Thanks for your detailed reproduction !

Since the fallback data are not persisted in cache, mutate is not able to access it directly. This is a expected behavior.

You can use useSWRConfig to access fallback data as a workaroud const { fallback } = useSWRConfig();

Would you mind to share your intention and actual use case for the pattern used in this example ? It would be helpful for us to build a better developer experience in the future.

promer94 avatar Apr 07 '23 05:04 promer94

I have a page with saved items. Each item can be removed from the list. The page is rendered on the server initially. And I use mutate with async function to get access to the data. The only way to fix it is to set revalidateIfStale: true, but in this case, the same data is fetched on the client on the first render. which is fine as a workaround, but seems weird given that I already have the data from the server in the fallback.

tonypizzicato avatar Apr 07 '23 09:04 tonypizzicato

And I've extracted a generic hook for those saved items and hidden items with the same logic. And it's used in different places (like the page itself, widgets, and other places). And the mutate itself is passed as an argument to some other function. So passing data from the fallback property is not that convenient when I have multiple places where the hook is used given that the data is already in (but not cached).

tonypizzicato avatar Apr 07 '23 12:04 tonypizzicato

@promer94 hi mem , i got the trouble with call swr from client after get init data from server my logic is

export const useUserProfile = () => { const endPoint = /api/profile?epath=${EProfilePath.GET_PROFILE}; console.log(endPoint); return useSWR<TProfileRes>(/api/profile?epath=${EProfilePath.GET_PROFILE}`, fetcher, { revalidateIfStale: true }); };

export const useSSRUserProfile = ({ fallbackData }: { fallbackData?: TProfileRes }) => useSWR<TProfileRes>(/api/profile?epath=${EProfilePath.GET_PROFILE}, fetcher, { fallbackData, });`

dinhhuudat avatar May 15 '23 09:05 dinhhuudat