-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
BaseShareLogList list refactor #38942
BaseShareLogList list refactor #38942
Conversation
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.
Can you please update the PR description to link to a GH for this work? I would like to have more context behind the work being done.
const betas = useBetas(); | ||
|
||
const searchOptions = useMemo(() => { | ||
const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); |
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.
Should this be outside of the function and then used as a dependency for useMemo()
? It seems wrong to be calling it inside this memo since it relies on outside data.
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.
Also, why is useMemo()
being done here instead of useEffect()
?
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.
- That would great but
OptionsListUtils.isPersonalDetailsReady(personalDetails);
is consuming data coming from theusePersonalDetailsHook
so it can't be moved outside the component. - I just tossed it in the useMemo responsible for
searchOptions
as it's also dependant onpersonalDetails
. UsinguseEffect
withsetState
is an anti-pattern that should punished by death in most 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.
so it can't be moved outside the component.
Sorry, this isn't really what I was suggesting. I was thinking of just moving it outside of useMemo()
but still keeping it inside the component. I'd still like to see if this is possible.
Using useEffect with setState is an anti-pattern that should punished by death in most cases.
Sounds good! I'll avoid the death penalty in that case then.
|
||
const updateOptions = useCallback(() => { | ||
if (!isMounted.current || !isOptionsDataReady) { | ||
isMounted.current = true; |
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.
isMounted
ref is strange to me as well. Is it really necessary? How could the options data be ready but the component not be mounted?
It seems like it would be better to:
- use a
ref
forsearchOptions
and have it's default value be what is in this early return - Update the
searchOptions
ref inside thisuseMemo()
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.
Alternative thought: Maybe each of these 4 properties should be their own distinct variable. Would that clean up the code at all?
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, I kinda bluntly repurposed isMounted
flag from the previous version of the component, but I agree, with isOptionsDataReady
it's totally unnecessary.
Fixed. Forgot to paste it in. |
const betas = useBetas(); | ||
|
||
const searchOptions = useMemo(() => { | ||
const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); |
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.
so it can't be moved outside the component.
Sorry, this isn't really what I was suggesting. I was thinking of just moving it outside of useMemo()
but still keeping it inside the component. I'd still like to see if this is possible.
Using useEffect with setState is an anti-pattern that should punished by death in most cases.
Sounds good! I'll avoid the death penalty in that case then.
|
I think it just doesn't seem to fit because it's like doing a double-memo almost. If the memo runs and the options data aren't ready, then a default set of options is used. When the memo runs again, and the options data are ready, then the real options are used. It should just not call the memo at all until the options data are ready. It feels like it should just be more simple than that.
|
@tgolen Good thinking and I see your point, but I have few additions:
As you can see it doesn't really matter that much whether the flag's value is calculated inside the useMemo callback function or outside. useMemo hook would still be called as it's dependant on the same data that the flag is. That's why it's logical to group calculations dependent on the same data set. In this case we won't get a perf boost as calculations of the flag are not very "expensive", but still it's something. The number of render cycles doesn't change on the position of the flag either. It's 2 in both cases. Before this refactoring it was 3 renders, so a 33% reduction ;) |
OK, I understand there is technically no difference. I can chalk this up to personal preference in that case and not let it be a blocker. Thanks for listening! |
@tgolen well, in that case I'm happy to make an exception :D |
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.
Hahaha, OK. Thanks! It looks like we should have a C+ review and test this as well?
@abdulrahuman5196 I think you were intended to be the C+ for this (from looking at the issue), so I've added you as a reviewer. Can you please complete the reviewer checklist on this? |
@lukemorawski This PR references #36038 issue which already has a PR - #38039. Is both PR related? Any background information on this PR? |
@abdulrahuman5196 sorry, wrong issue number. Fixing that now |
@rushatgabhane I think this review is for you. Feel free to takeover. If not I can review as well. |
@abdulrahuman5196 For the sake of urgency, let's just move forward with you doing the C+ review for this if you don't mind. |
Reviewer Checklist
Screenshots/Videos |
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.
@lukemorawski
Bug: "No results found" is shown even if results are there.
- Go to share log page
- search for a user
@lukemorawski Can you take a look at that bug, please? |
yep, I'm resolving some merge conflicts on another PR. Will take a look at that after that. |
@tgolen @rushatgabhane fixed |
🚀 Deployed to staging by https://github.com/cristipaval in version: 1.4.61-0 🚀
|
🚀 Deployed to staging by https://github.com/cristipaval in version: 1.4.61-0 🚀
|
🚀 Deployed to production by https://github.com/Julesssss in version: 1.4.61-8 🚀
|
Details
This PR replaces deprecated
<OptionsSelector />
component in favour of<SelectionList />
and also refactors internal logic, streamlining howsearchOptions
are created, reducing the render count.Fixed Issues
$ #20354
PROPOSAL: no proposal
Tests
Offline tests
QA Steps
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
native.android.mov
Android: mWeb Chrome
web.android.mov
iOS: Native
native.ios.mov
iOS: mWeb Safari
web.ios.mov
MacOS: Chrome / Safari
web.desktop.mov
MacOS: Desktop
native.desktop.mov