Skip to content

feat: add getInfiniteKey to mutate the cache for useSWRInfinite #1257

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

Merged
merged 10 commits into from
Jul 12, 2021

Conversation

koba04
Copy link
Collaborator

@koba04 koba04 commented Jul 1, 2021

fixes #1156

This PR adds a new API called mutateInfinite, which is a mutation function for useSWRInfinite and based on #1156 (comment).

This PR adds a new API called getInfiniteKey to get a key to mutate cache data for useSWRInfinite, which receives a key loader function and returns the key for the cache data.

I feel this is still in discussion and have not meet an agreement, so this is just a POC.

@koba04 koba04 changed the title feat: mutateInfinite feat: add mutateInfinite Jul 1, 2021
@codesandbox-ci
Copy link

codesandbox-ci bot commented Jul 1, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit ef31a87:

Sandbox Source
SWR-Basic Configuration
SWR-States Configuration
SWR-Infinite Configuration
SWR-SSR Configuration

@shuding
Copy link
Member

shuding commented Jul 1, 2021

Love this. I got another question, how can we have the global mutate function when we are using the cache provider?

@koba04 koba04 force-pushed the use-mutate-infinite branch 2 times, most recently from ccc799c to efb1459 Compare July 6, 2021 14:12
src/index.ts Outdated
@@ -1,5 +1,5 @@
// Core APIs
export { SWRConfig, mutate, createCache } from './use-swr'
export { SWRConfig, mutate, createCache, mutateCustomCache } from './use-swr'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if we want to expose the internalMutate here since createCache has already covered the similar usage

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it's not the best way to support the use case. We might have to find out another solution like exporting a function that returns a key like INFINITE_PREFIX + getFirstPageKey(getKey) rather than exporting a mutate funciton.

await screen.findByText('data:page-test-12-0:2')

await act(() =>
mutateInfinite(index => `page-test-12-${index}`, 'local-mutation', false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

users have the keyLoader definition, at the same time they also have the createCache to get the mutate function, then combining both of them can also achieve the similar approach?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean like mutate(getInfiniteKey(getKey), 'local-mutation', false)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that would be nice!

@koba04
Copy link
Collaborator Author

koba04 commented Jul 6, 2021

@shuding

how can we have the global mutate function when we are using the cache provider?

That concern makes sense.
Currently, the global mutate function seems not to work correctly with a custom cache. Is it correct?

I've added mutateCustomCache as a mutate function that works with a custom cache for mutateInfinite 7424dcc.
mutateInfinite works correctly with a custom cache by using the mutateCustomCache efb1459.

But I feel this is not the best way for the feature.
Before working this, should we fix the issue how the global mutate function deals with a custom cache?

Another solution is #1257 (comment)

@pacocoursey pacocoursey removed their request for review July 9, 2021 18:18
@koba04 koba04 changed the title feat: add mutateInfinite feat: add getInfinitePageKey to mutate cache data of useSWRInfinite Jul 12, 2021
@koba04 koba04 changed the title feat: add getInfinitePageKey to mutate cache data of useSWRInfinite feat: add getInfiniteKey to mutate cache data of useSWRInfinite Jul 12, 2021
@koba04 koba04 changed the title feat: add getInfiniteKey to mutate cache data of useSWRInfinite feat: add getInfiniteKey to mutate the cache for useSWRInfinite Jul 12, 2021
@koba04 koba04 force-pushed the use-mutate-infinite branch from a1ce233 to 8e6afc9 Compare July 12, 2021 15:28
@koba04
Copy link
Collaborator Author

koba04 commented Jul 12, 2021

I've updated this PR to add getInfiniteKey rather than mutateInfinite, which is based on the @huozhi's comment.

Implementing getInfiniteKey is simpler than mutateInfinite and is able to support a custom cache 👍

Copy link
Member

@shuding shuding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I think this is the best choice for now until we have a better way to work around custom cache providers.

@shuding shuding merged commit 9e1e9fb into vercel:master Jul 12, 2021
@koba04
Copy link
Collaborator Author

koba04 commented Jul 12, 2021

Thank you!🚀

@koba04 koba04 deleted the use-mutate-infinite branch July 13, 2021 06:59
@nicholaschiang
Copy link

nicholaschiang commented Jul 26, 2021

@shuding @koba04 have you added this API to the documentation yet? If not, could you?

@nicholaschiang
Copy link

@shuding could you please release this?

@shuding
Copy link
Member

shuding commented Jul 27, 2021

@nicholaschiang A new beta released is there, please check! We will document new APIs when it's stable.

@nicholaschiang
Copy link

nicholaschiang commented Jul 31, 2021

@shuding this doesn't seem to support mutating based on current data. It's not included in your tests and it's not working here:

// I have an updated message and I need to mutate the list of messages.
const message = { ...prev, subject: 'This is an updated value.' };
await mutate(
  getInfiniteKey(getKey), 
  (data?: MessagesRes[]) => data?.map((messages: MessageRes) => {
    // `data` is always `undefined` even when I know the list has loaded.
    const idx = messages.findIndex((m) => m.id === message.id);
    if (idx < 0) return messages;
    return [...messages.slice(0, idx), message, ...messages.slice(idx + 1)];
  }), 
  false
);

@koba04
Copy link
Collaborator Author

koba04 commented Aug 1, 2021

@nicholaschiang I've made a PR to confirm your case.
#1319
This seems to work well in the test case.

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

Successfully merging this pull request may close these issues.

Cannot use global mutate with useSWRInfinite
4 participants