ORG-83 userInvitations in useOrganizationList#1520
Conversation
🦋 Changeset detectedLatest commit: 34484b6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
a5c0c58 to
6f059cf
Compare
| type CoreClerkContextWrapperProps = { | ||
| clerk: Clerk; | ||
| children: React.ReactNode; | ||
| swrConfig?: any; |
There was a problem hiding this comment.
Could you please explain why we need this?
There was a problem hiding this comment.
This is passed from MockClerkProvider down to CoreOrganizationProvider in order to clear swr cache between tests
| <ClientContext.Provider value={clientCtx}> | ||
| <SessionContext.Provider value={sessionCtx}> | ||
| <OrganizationContext.Provider value={organizationCtx}> | ||
| <OrganizationProvider {...organizationCtx.value}> |
There was a problem hiding this comment.
I guess we're treating this differently because of swrConfig... Not sure how I feel about this small discrepancy to be honest - if this is a testing-only issue, we might be able to find a different solution that works for the tests. What was the original issue?
There was a problem hiding this comment.
We need a way to clear cache between tests. The recommended way from the SWR docs is this
Wrapping our CoreClerkContextWrapper with will not work. I verified this by logging the results of useSWRConfig inside our useOrganization while tests where running.
My solution was to expose a OrganizationProvider instead of the "low-level" context and include the <SWRConfig/> provider inside of the OrganizationProvider.
☝️ This is now working as expecting.
There was a problem hiding this comment.
I see that the cache provider follows the following interface:
interface Cache<Data> {
get(key: string): Data | undefined
set(key: string, value: Data): void
delete(key: string): void
keys(): IterableIterator<string>
}
Did you try wrapping the test contexts with a SWRConfig that uses a "noop" cache provider, eg:
{
get: () => undefined,
set: noop,
delete: noop,
keys: () => []
}
so that we don't need to reset it between the tests?
There was a problem hiding this comment.
I don't see why this would help. It seemed like the useSWRConfig within useOrganization would return the default values, as it couldn't reach the correct provider of SWRConfig.
For example is I was passing <SWRConfig value={{ dedupingInterval: 0 }}/> the useSWRConfig would return {dedupingInterval: 2000} which is the default value
There was a problem hiding this comment.
Does this mean that a SWRConfig provider is found deeper in the tree so you cannot override the defaults in the tests?
| })); | ||
| } | ||
|
|
||
| function cacheKey(type: 'userInvitations', user: UserResource, pagination: GetUserOrganizationInvitations) { |
There was a problem hiding this comment.
Do we care about typing these objects here? Do you think this would be enough? If it's generic enough in can be used in other similar places as well - other hooks using swr for example.
| function cacheKey(type: 'userInvitations', user: UserResource, pagination: GetUserOrganizationInvitations) { | |
| function cacheKey(...keys: Array<string | number | undefined>) { |
There was a problem hiding this comment.
I think you are correct. Although swr@2 seems to automatically parse objects as keys, which will make this function obsolete
There was a problem hiding this comment.
We need to make sure to check whether swr uses referential equality checks or if it somehow builds a scalar value by paring the object's values - otherwise we might risk invalidating the cache on every render.
bf065dd to
9a215b6
Compare
8d2af63 to
7ce7885
Compare
| const [paginatedPage, setPaginatedPage] = useState(shouldUseDefaults ? 1 : userInvitations?.initialPage ?? 1); | ||
|
|
||
| // Cache initialPage and initialPageSize until unmount | ||
| const initialPageRef = useRef(shouldUseDefaults ? 1 : userInvitations?.initialPage ?? 1); |
There was a problem hiding this comment.
❓ Do we need the last default fallback? Can't we ensure that the initialPage attribute always has a value?
There was a problem hiding this comment.
Follow-up question? Do we need a ref for this?
There was a problem hiding this comment.
initialPage does not always have a value as someone can simply pass as params the following
useOrganizationList({infinite:true})Here we want to not use the defaults in general but use the default value of initialPage
| return userInvitationsData?.total_count ?? 0; | ||
| }, [triggerInfinite, userInvitationsDataInfinite, userInvitationsData]); | ||
|
|
||
| const isomorphicIsLoading = triggerInfinite ? userInvitationsLoadingInfinite : userInvitationsLoading; |
There was a problem hiding this comment.
❓ What does isomorphic mean in this context? It feels that it's a bit confusing.
There was a problem hiding this comment.
I needed a way to introduce parity between the returned values of useSWR and useSWRInfinite.
based on the params received in the hook return the appropriate values
There was a problem hiding this comment.
The naming still feels a bit off. I'd just remove the isomorphic prefix.
There was a problem hiding this comment.
Sure, i'll update this shortly in a following PR
| setSize, | ||
| mutate: userInvitationsInfiniteMutate, | ||
| } = useSWRInfinite(getInfiniteKey, ({ initialPage, initialPageSize, status }) => { | ||
| return !clerk.loaded || !user |
There was a problem hiding this comment.
❓ I believe this hook should trigger the fetch only if triggerInfinite is set to true
There was a problem hiding this comment.
It does, you can check getInfiniteKey. The triggering is decided based on the key not the fetcher function. I updated that part and removed the conditional from this place to avoid confusions
| return userInvitationsData?.total_count ?? 0; | ||
| }, [triggerInfinite, userInvitationsDataInfinite, userInvitationsData]); | ||
|
|
||
| const isomorphicIsLoading = triggerInfinite ? userInvitationsLoadingInfinite : userInvitationsLoading; |
There was a problem hiding this comment.
The naming still feels a bit off. I'd just remove the isomorphic prefix.
…seOrganizationList` - Improves DX of useOrganizationList
… introduce OrganizationProvider We needed to wrap <OrganizationContext.Provider/> with SWRConfig provider so that useSWR hooks can read from the correct context in tests.
…nList + expose isLoading and isFetching
|
This PR has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Type of change
Packages affected
@clerk/clerk-js@clerk/clerk-react@clerk/nextjs@clerk/remix@clerk/types@clerk/themes@clerk/localizations@clerk/clerk-expo@clerk/backend@clerk/clerk-sdk-node@clerk/shared@clerk/fastify@clerk/chrome-extensiongatsby-plugin-clerkbuild/tooling/choreDescription
npm testruns as expected.npm run buildruns as expected.This PR
UserOrganizationInvitationandUserOrganizationInvitationResourceuserInvitationsuserInvitationswhen fetched fromuseOrganization(Very useful from infinite scrolling)You might be familiar with
OrganizationInvitationthat already exists in our codebase.Both
UserOrganizationInvitationandOrganizationInvitationdescribe the same entity. The former is from the perspective of a user where the later from the perspective of an organization.Exposed API