Avoiding surprises with RefreshTokens and unexpected re-renders #44
ronnybremer
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Using yew-oauth2 now for a while I encountered a little snag when dealing with refresh tokens. So I thought I share my experiences here in case they might help others.
Consider a simple app, which requires you to login. You probably set up a global context holding the current authentication information, like user name, access token and maybe display name.
This might look like this:
The AppContext is then inherited throughout the app and can be accessed in function components and structural components.
Whenever the OAuth2Context changes, an action will be sent to the reducer, AppStateAction::Login if the context is authenticated or AppStateLogout otherwise. Also a log out button is sending the latter to the reducer.
Yew will automatically re-render all sub components of the AppContext on any such change.
However, as soon as you start to use RefreshTokens you will notice, that a re-render also happens whenever a new token has been received. Which makes sense, as every sub component needs to get the new token, so they would re-render. But this isn't particularly user friendly. Consider you are filling out a form, typing a message in a text box or watching a video. The token refreshes and you form will reset or your video will start from the beginning.
Luckily, Yew is offering the
use_reducer_eq
hook, which according to the documentation will only re-render, whenPartialEq
on the AppContext returns false.So the obvious approach would lead you to:
This will effectively suppress the re-render as intended, however, it will also prevent the token from getting updated. Even though the
reduce()
function above returns a new AppContext on AppStateAction::UpdateToken, it appears to not get used by existing sub components.After reaching out on the always helpful Discord channel of Yew, @WorldSEnder pointed me in the right direction. To summarize:
So this is the code which I am using now and it remedies the issue.
token
inside of AppContext is replaces by a RefCell, which can be mutated even on non-mutable self.The AppStateAction::UpdateToken match arm is replacing the value of the RefCell
token
and then returnsself
, thereby replacing the token on both the old instance of AppContext as well as the new instance (for re-renders or new components).Re-renders don't happen until the
user_name
changes but theget_access_header()
function will always return the most current token.Beta Was this translation helpful? Give feedback.
All reactions