-
Notifications
You must be signed in to change notification settings - Fork 216
fix(metrics): Add useLocalStorageSync hook for reactive changes to localstorage
#19776
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
base: main
Are you sure you want to change the base?
Conversation
LZoog
left a comment
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.
Code LGTM, + tested locally and it works!
| * }, [currentAccountUid]); | ||
| * ``` | ||
| */ | ||
| export function useLocalStorageSync(key: string) { |
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.
Nice!
| // Get metricsEnabled from accounts object, safely handling undefined values | ||
| const accountMetricsEnabled = useMemo(() => { | ||
| if (!currentAccountUid || !accounts) { | ||
| return 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.
If I'm not signed into an account, this value is undefined and so the Nimbus experiments don't get fetched. Should this be true instead?
Also, do you plan to address the 1. and 2. points of the ticket in this PR? I think this only covers the 3rd case, but the other 2 should be easy at least if you want to do them here or in a quick follow up.
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.
I believe 2. was already done
If I'm not signed into an account, this value is undefined and so the Nimbus experiments don't get fetched. Should this be true instead?
I can change it to true it is confusing, the experiments should get called since the check is undefined === false below
| accountMetricsEnabled, | ||
| ]); | ||
|
|
||
| const value: NimbusContextValue = useMemo(() => ({ |
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.
Hm, when I navigate from email-first to sign-in after a fresh /clear, I get this error in the console:
I wouldn't expect this to rerender at this point, given local storage hasn't changed yet? Or maybe it did change due to Glean entry stuff and we only need to rerender on currentAccountUid and not accounts if that changes there? Looking at getAccountInfo in Signin Container, I guess we do update it with setCurrentAccount at this point, but we don't have the UID so we shouldn't rerender there yet 🤔
I don't see the error again at least when I enter the account password and the useEffect correctly runs, it seems to work, which is neat! 🎉
... Though, when I signed into an unverified account and confirmed it, when I was redirected to Settings with that account, the useEffect reran again for some reason, and accountsMetricsDisabled is set to 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.
@LZoog I havent been able to reproduce this :/
Because
useEffectdon't trigger re-renders when values change in the same tabThis pull request
useLocalStorageSynchook using React'suseSyncExternalStorefor reactive localStorage monitoringlocalStorageChangeevents when Storage class modifies localStorage valuesNimbusContextto useuseLocalStorageSyncfor trackingcurrentAccountUidandaccountsdataIssue that this pull request solves
Closes: https://mozilla-hub.atlassian.net/browse/FXA-12738
Checklist
Other information (Optional)
This change improves the reactivity of the Nimbus experimentation system by ensuring that metrics preference changes are immediately reflected without requiring page reloads. The implementation uses React 18's
useSyncExternalStoreAPI for proper external state synchronization.