Skip to content
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

Add useMemo util for htmlIdGenerator + update EuiDataGrid's IDs to not change on every rerender #5133

Merged
merged 16 commits into from
Sep 9, 2021

Conversation

cee-chen
Copy link
Member

@cee-chen cee-chen commented Sep 2, 2021

Summary

@kqualters-elastic recently raised that our EuiDataGrid IDs were regenerating on every change/rerender (e.g. click/sort/paginate events, etc.). The way to fix this is to memoize the generated ID.

I opted to create a custom hook helper with useRef, as the generated ID isn't really meant to change unless the component fully unmounts/mounts, and I think useRef conveys that slightly more accurately than state.

Per @chandlerprall's excellent breakdown and @breehall's work, I've determined that useMemo definitely beats out useRef in terms of usage and updated this PR accordingly!

Before

(Note the yellow flash on the id props on change)

before

After

after

Checklist

- [ ] Check against all themes for compatibility in both light and dark modes
- [ ] Checked in mobile
- [ ] Checked in Chrome, Safari, Edge, and Firefox
- [ ] Props have proper autodocs and playground toggles

- [ ] Checked for breaking changes and labeled appropriately

  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

@cee-chen
Copy link
Member Author

cee-chen commented Sep 2, 2021

As a note, I only updated EuiDataGrid for now to get early comments out of the way, but I'm planning on doing a pass on all components with rerendering generated IDs. FWIW It's not all components using htmlIdGenerator, as some of them are either using useState/useRef already, or are class components that store the generated ID on init which also doesn't rerender. Do y'all have any preference as to whether those updates should be a separate PR, or if I should continue extending this PR?

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

- that creates a memoized ID, preventing the issue of re-randomized IDs on every component change
…props)

+ update EuiCollapsibleNav as an example of real-world usage
@cee-chen cee-chen changed the title Add useRef util for htmlIdGenerator + update EuiDataGrid's IDs to not change on every rerender Add useMemo util for htmlIdGenerator + update EuiDataGrid's IDs to not change on every rerender Sep 2, 2021
@cee-chen
Copy link
Member Author

cee-chen commented Sep 3, 2021

👋 Hey y'all! I ended up squashing in my changes in a rebase, since there were many of them after our recent team discussion.

  1. The initial setup (c5bd90b) now uses useMemo instead of useRef, and is much awesomer for it! Thanks Chandler and Bree!
    • I also renamed the fn to differentiate it more clearly from the original generator, and renamed the params from idPrefix->prefix for brevity
  2. I added 5921ac7 which adds a 3rd idFromProps param, and an example conversion within EuiCollapsibleNav. I'm not super in love with the naming of this one though, does anyone have any ideas? Here's the options I tossed around, not sure if they're any better:
    • idFromProps
    • customId
    • overrideId
  3. I added docs in 1009e4c and would super appreciate feedback there!! It'll be my first time officially adding copy/docs examples and I'm not totally sure I nailed it 😅

Thanks y'all! Locally, I'll keep beavering away at converting more src/components/ to the new util!

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

@cee-chen
Copy link
Member Author

cee-chen commented Sep 7, 2021

👋 Re-pinging for review since this is potentially blocking @breehall's PR!

@thompsongl thompsongl self-requested a review September 7, 2021 20:16
Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mainly just looked at the new hook and it's associated docs. Had a couple of suggestions.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

Co-authored-by: Caroline Horn <549577+cchaos@users.noreply.github.com>
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love how simple this hook turned out to be!

src/services/accessibility/html_id_generator.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 LGTM, only checked in Chrome though and only the Docs of the new hook.

@cee-chen
Copy link
Member Author

cee-chen commented Sep 9, 2021

I just did another quick QA pass and noticed all but 1 of the CodeSandbox links on the HTML ID generator demos are broken because they export named components instead of a default function 🙈 I'll fix that here shortly!

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

- Changed exports from named exports to default in order for demos to work in CodeSandbox

- Added `htmlIdGenerator` namespacing for clarity to all prefix/suffix sections

- Fixed casing on `bothPrefixSuffix.js` to snake_casing (per rest of codebase)

- Fixed casing of all source & snippet vars to camelCasing

- Fixed `sufix` typo
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5133/

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
Codesandbox links are working, except for the one with the new hook, which is to be expected before it's released.

@cee-chen
Copy link
Member Author

cee-chen commented Sep 9, 2021

Ahh phew, thanks a million Greg, I was worried I'd done something wrong there! 😅

Merging this in now!

@cee-chen cee-chen merged commit eca5d49 into elastic:master Sep 9, 2021
@cee-chen cee-chen deleted the use-htmlidgenerator branch September 9, 2021 16:37
@thompsongl
Copy link
Contributor

thompsongl commented Sep 9, 2021

Ahh phew, thanks a million Greg, I was worried I'd done something wrong there!

Yeah we currently don't have a method to use a pre-release EUI package in codesandbox, so it uses the latest release. So any new things components, services, or props in a PR are unavailable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants