Description
Description
Seemingly since this PR to upgrade @edx/frontend-platform
to React Router v6, components seem to need to be explicitly subscribed to the AppContext
when retrieving the authenticated user object within a component as opposed to continuing to rely on getAuthenticatedUser
.
This change in behavior resulted in several critical user flows regressing/breaking on production for the frontend-app-learner-portal-enterprise
MFE since this PR merged (e.g., infinite loading spinners because the MFE expects getAuthenticatedUser
to always represent the full metadata about the user, and it no longer always does). The React Router v6 upgrade was since reverted in this MFE as a result.
Context
The initialize
function (entry point for MFEs) allows consumers to optionally hydrateAuthenticatedUser
which tells @edx/frontend-platform
to make an API call (http://localhost:18000/api/user/v1/accounts/<username>
)to retrieve additional metadata about the user (e.g., name, profile image, etc.).
For MFEs, there's generally 2 mechanisms to extract the user's metadata from @edx/frontend-platform
, both of which are patterns used by MFEs today:
getAuthenticatedUser
The getAuthenticatedUser
function (docs / source) ultimately calls the AxiosJwtAuthService.getAuthenticatedUser
function which simply returns whatever this.authenticatedUser
it has available.
function MyComponent() {
const authenticatedUser = getAuthenticatedUser();
return (
<div>
<p>Authenticated Username: <strong>{authenticatedUser.username}</strong></p>
<p>
Authenticated user's name:
<strong>{authenticatedUser.name}</strong>
(Only available if user account has been fetched)
</p>
</div>
);
}
AppContext
The AppContext
context provider includes (presumably) the same authenticatedUser
object as should be returned by getAuthenticatedUser()
. However, by subscribing to the AppContext
, any time the authenticatedUser
changes, the component is guaranteed to re-render with the latest authenticatedUser
data.
function MyComponent() {
const { authenticatedUser } = useContext(AppContext);
return (
<div>
<p>Authenticated Username: <strong>{authenticatedUser.username}</strong></p>
<p>
Authenticated user's name:
<strong>{authenticatedUser.name}</strong>
(Only available if user account has been fetched)
</p>
</div>
);
}
Regression
The regression noticed in frontend-app-learner-portal-enterprise
and also reproducible in frontend-platform example MFE is that after the React Router v6 upgrade in @edx/frontend-platform
, relying on getAuthenticatedUser
is not guaranteed to have the correct metadata MFE developers might expect.
When debugging, it was observed that when relying on getAuthenticatedUser
before React Router v6 upgrade, the component first renders with the minimal set of user metadata but after a re-render of the component, it then contains the full metadata as expected.
Now, after React Router v6 upgrade, there is only a single call to getAuthenticatedUser
returning the minimal user metadata (i.e., missing the hydrated metadata from the API). This seems to be an unexpected change in behavior.
The known workaround is to migrate components away from getAuthenticatedUser()
in favor of pulling from AppContext
instead to ensure the component is properly re-rendered in order to have the fully hydrated user metadata. That said, an ideal fix would ensure getAuthenticatedUser()
always returns the same metadata as returned by AppContext
as most consumers would likely expect both mechanisms to have the same behavior, returning the same hydrated user metadata, when used within a component.
Actual
The behavior after React Router 6 upgrade shows a single console.log
of the minimal authenticated user metadata. It is missing the full hydrated user metadata including properties like profileImage
, etc. until something triggers a re-render of the component.

Expected
The behavior before React Router v6 upgrade shows the console.log
of the minimal authenticated user metadata first, then an automatic component re-render which then forces another console.log
including the full authenticated user metadata instead.

Metadata
Metadata
Assignees
Type
Projects
Status