-
Notifications
You must be signed in to change notification settings - Fork 2
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
feat: Add Stable/useStable and use for GridTableProps.rows/columns #933
base: main
Are you sure you want to change the base?
Conversation
@@ -18,7 +18,7 @@ import { | |||
Filters, | |||
GridColumn, | |||
GridDataRow, | |||
GridTable, | |||
GridTableUnsafe as GridTable, |
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.
@bdow I'd added GridTableUnsafe
as an alias with the old/as-is props, but kinda wondering if maybe we should take this opportunity to introduce Table
as the new component name, which has the new/safe props, and GridTable
is the old/deprecated component name.
That would make this roll out a lot easier, b/c all exists clients of GridTable
wouldn't have to be either a) renamed over to the GridTableUnsafe
alias, or b) have their non-memoed rows/columns fixed.
...although arguably b) would be a great forcing function, it just means rolling this out will be a lot more work/updates.
Wdyt?
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.
Yea, I like that idea to rename the "new" to just Table
. Then we won't block updating Beam on updating existing GridTable implementations.
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.
Cool! Pushed up the "GridTable stays the same, Table is the new safe one".
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! Would love to do a FE Guild discussion on this.
src/hooks/useStable.ts
Outdated
// With this extension, we could almost get away without our own `useStable` hook, | ||
// but we can't use the extension mechanism to restrict useMemo's `deps` to be | ||
// `ReadonlyArray<StableDep>`. | ||
function useMemo<T>(factory: () => T, deps: ReadonlyArray<unknown> | undefined): Stable<T>; |
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.
@bdow FWIW during demos, answering a question for @khalidwilliams , I'm kinda thinking we should back away from this change, which "upgrades" useMemo
to produce stable values, and have useStable
be the only one that can make stable values.
The reason is that, with the TS typing, I'm unable to "upgrade" useMemo
's dependency list to be only stable values, and it is precisely this restriction that we'd need to have prevented the bug I fixed.
I.e. the bug I fixed, the const columns = useMemo(...)
was "already useMemo-d" but the elevations
dependency was itself an unstable array:
So, really, the fix we need to be 100% bulletproof to performance is not just: a) the user uses useStable
or useMemo
for the rows/columns props, but also b) any dependencies the user used for useStable
or useMemo
must themselves be stable.
And I cannot "fix" useMemo
to have this restriction (it would also be a huge breaking change), so I think we'd have to just say "now all const rows = useMemo(...)
s have to be const rows = useStable(...)
s" and deal with the fallout.
I'm pretty convinced this is the right direction, even though it's a more disruptive change, b/c all of our useMemo
s lines need to become useStable
s--and also make sure their dependencies are stables, but that's the whole point, we need to have the stableness check be transitively applied to dependencies of our dependency.
Wdyt?
This PR attempts to solve the "damn it,
columns
was not memo'd so we blew up the table's performance and/or messed up the DOM focus" bugs by forcingcolumns
androws
to really be stable.GridTableProps.rows
andcolumns
with theStable<...>
marker/branded typeuseMemo
oruseStable
useMemo
's return type to beStable<T>
so existinguseMemo
-d values will be considered stableuseStable
is a new hook that is "justuseMemo
" but requires its own dependency array to be stable, which is safer thanuseMemo
which to date just has a handful of eslint heuristics to check invalid depsGridTableUnsafe
that is "the old non-stable API" to ease the transitionGridTable
as-is, and introduce a newGridTableSafe
, and move pages over to it one-by-one ... tempted to just pull the bandaid with the breaking change, but it will be a large roll out effort