-
Notifications
You must be signed in to change notification settings - Fork 364
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
refactor: [M3-8981] - User Preferences optimization with selector pattern (Part 1) #11386
refactor: [M3-8981] - User Preferences optimization with selector pattern (Part 1) #11386
Conversation
preferenceKey="linodes_group_by_tag" | ||
preferenceOptions={[false, true]} | ||
toggleCallbackFn={sendGroupByAnalytic} | ||
> | ||
{({ | ||
preference: linodesAreGrouped, | ||
togglePreference: toggleGroupLinodes, | ||
}: PreferenceToggleProps<boolean>) => { |
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 improved the type-safety of PreferenceToggle
. These explicit type annotations are no longer needed because the type is now properly inferred
@@ -14,9 +14,11 @@ export interface DismissedNotification { | |||
label?: string; | |||
} | |||
|
|||
export interface ManagerPreferences extends UserPreferences { |
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 extends
was causing type-safety issues. It basically made ManagerPreferences extend Record<string, any>
, which allowed any string
key. Removing the extends
allow us to be more strict.
avatarColor?: string; | ||
backups_cta_dismissed?: boolean; | ||
collapsedSideNavProductFamilies?: number[]; |
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.
These were types missing... Now that type-safety is better, developers will see type errors that will catch this
}); | ||
|
||
export const useMutatePreferences = (replace = false) => { | ||
const { data: preferences } = usePreferences(!replace); |
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 removed this use of usePreferences
and implemented mutationFn
differently.
Using usePreferences
here would cause any components that uses useMutatePreferences
to re-render when preferences update. This change will eliminate that path to extra re-renders.
const [collapsedAccordions, setCollapsedAccordions] = React.useState< | ||
number[] | ||
>(preferences?.collapsedSideNavProductFamilies ?? []); |
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.
We don't need to use extra state here. Because our user preferences optimistically update, we can essentially treat it as state.
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.
Had to make some changes here to improve type-safety. See other comment in LinodesLanding.tsx
const { data: collapsedSideNavPreference } = usePreferences( | ||
(preferences) => preferences?.collapsedSideNavProductFamilies | ||
); |
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 the new pattern in-use! ✨
Before: The primary nav would re-render when any preference was updated
After: The primary nav will only re-render when preferences.collapsedSideNavProductFamilies
updates 🎉
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 could be unrelated, but I’m noticing that PrimaryNav re-renders when navigating to Create Image
, while it doesn’t re-render when selecting any products from the Side Nav or any other Create {Product}.
understood - it's a Create Image, but is PrimaryNav supposed to get re-rendered in such cases??
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.
Yeah, that is unrelated. From my understanding, the primary nav will re-render when we change routes no matter what.
Coverage Report: ✅ |
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, this was a cool improvement to see demoed and it will be good to optimize preference-use throughout the app!
Confirmed:
- The new pattern is easy to understand
- No regressions with primary navigation and collapsed state is correctly saved in user preferences
- Toggling other preferences does not rerender the primary navigation; only changes to the collapsed state
Screen.Recording.2024-12-11.at.9.11.52.AM.mov
Co-authored-by: Mariah Jacobs <[email protected]>
Cloud Manager UI test results🎉 469 passing tests on test run #9 ↗︎
|
Cloud Manager E2E Run #6959
Run Properties:
|
Project |
Cloud Manager E2E
|
Branch Review |
develop
|
Run status |
Passed #6959
|
Run duration | 31m 11s |
Commit |
abf05ca641: refactor: [M3-8981] - User Preferences optimization with selector pattern (Part ...
|
Committer | Banks Nussman |
View all properties for this run ↗︎ |
Test results | |
---|---|
Failures |
0
|
Flaky |
3
|
Pending |
2
|
Skipped |
0
|
Passing |
469
|
View all changes introduced in this branch ↗︎ |
Description 📝
usePreferences
hookNote
This is just part 1, which introduces the pattern and uses it in a small number of places. I will follow up this PR with a part 2 (and maybe 3) to implement the pattern throughout the app.
Preview 📷
Important
No UI changes expected
How to test 🧪
Author Checklists
As an Author, to speed up the review process, I considered 🤔
👀 Doing a self review
❔ Our contribution guidelines
🤏 Splitting feature into small PRs
➕ Adding a changeset
🧪 Providing/improving test coverage
🔐 Removing all sensitive information from the code and PR description
🚩 Using a feature flag to protect the release
👣 Providing comprehensive reproduction steps
📑 Providing or updating our documentation
🕛 Scheduling a pair reviewing session
📱 Providing mobile support
♿ Providing accessibility support
As an Author, before moving this PR from Draft to Open, I confirmed ✅