-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
Fix race condition in WithPermissions #5822
Conversation
When an app has two components calling WithPermissions on the same render phase, a race condition used to lead the second call to never return the actual permissions.
expect(renders).toBe(1); // does not rerender when the getPermissions returns the same permissions | ||
}); | ||
|
||
it('can be called by two independent components', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test used to fail before the patch
@@ -13,7 +13,7 @@ const emptyParams = {}; | |||
|
|||
// keep a cache of already fetched permissions to initialize state for new | |||
// components and avoid a useless rerender if the permissions haven't changed | |||
const alreadyFetchedPermissions = { '{}': [] }; | |||
const alreadyFetchedPermissions = { '{}': undefined }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was another regression introduced in 3.11. Before, WithPermissions injected undefined
on mount. After, it injected an empty array.
@@ -71,7 +71,7 @@ const usePermissionsOptimized = (params = emptyParams) => { | |||
error, | |||
}); | |||
}); | |||
}, [getPermissions, params, setState]); | |||
}, [getPermissions, key]); // eslint-disable-line react-hooks/exhaustive-deps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is done on purpose, and there is no way around it
When an app has two components calling
<WithPermissions>
on the same render phase, a race condition used to lead the second call to never return the actual permissions.Foo
was rendered once with empty permissions, then rerendered with the permissions Fetched from the authProvider.Bar
was only rendered once, with empty permissions.This was a bug due to the permissions from the authProvider being compared to the cache rather than to the initial state.