Skip to content

Conversation

@paula-stacho
Copy link

@paula-stacho paula-stacho commented Jan 23, 2026

✍️ Proposed changes

There is a flickering related to re-rendering the Combobox (with multiselect) - see codesandbox.

This is issue is visible in Compass - https://jira.mongodb.org/browse/COMPASS-9891

Looking into the implementation, I found that the selection has been initialized after the 1st render (in the 1st render it is always null). Several styles depend on isMultiselectWithSelections, so this has been causing the flickering (there is still some flicker but not as obvious). Moving the initialization from useEffect to setState avoids this.

🎟 Jira ticket: LG-5469

✅ Checklist

For new components

  • I have added my new package to the global tsconfig
  • I have added my new package to the Table of Contents on the global README
  • I have verified the Live Example will look as intended on the design website.

For bug fixes, new features & breaking changes

  • I have added stories/tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)
  • I have run pnpm changeset and documented my changes

🧪 How to test changes

@paula-stacho paula-stacho requested a review from a team as a code owner January 23, 2026 13:25
@paula-stacho paula-stacho requested review from adamrasheed, Copilot and tsck and removed request for a team January 23, 2026 13:25
@changeset-bot
Copy link

changeset-bot bot commented Jan 23, 2026

🦋 Changeset detected

Latest commit: 2b0d1fa

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@leafygreen-ui/combobox Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a flickering issue in the Combobox component by initializing the selection state immediately during render rather than after the first render through a useEffect hook. The flickering occurred because styles dependent on isMultiselectWithSelections were being calculated based on null selection in the initial render.

Changes:

  • Replaced deferred initialization of selection state via useEffect with immediate initialization using useState initializer function
  • Moved validation logic inline to the useState initializer

@paula-stacho paula-stacho force-pushed the LG-5469 branch 2 times, most recently from 68f1a50 to 090f3c2 Compare January 23, 2026 13:33
Comment on lines +187 to +199
const [selection, setSelection] = useState<SelectValueType<M> | null>(() => {
if (initialValue) {
if (isArray(initialValue)) {
// Ensure the values we set are real options
const filteredValue =
initialValue.filter(value => isValueValid(value)) ?? [];
return filteredValue as SelectValueType<M>;
} else {
if (isValueValid(initialValue as string)) {
return initialValue;
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

It appears we have some regression in our tests where initial values are not being properly set on single selection. I believe this might be because later on in the file we have a useEffect that checks if the selection has changed, and updates the selection.

  // onSelect
  // Side effects to run when the selection changes
  useEffect(() => {
    const hasSelectionChanged =
      !isUndefined(prevSelection) &&
      ((isArray(selection) && !isNull(prevSelection)) ||
        isString(selection) ||
        isNull(selection)) &&
      !isEqual(selection, prevSelection);

    if (hasSelectionChanged) {
      onSelect();
    }
  }, [onSelect, prevSelection, selection]);

Because we previously had the extra render, selection was initially null then the selection would be set in initialValue, triggering the 2nd render where hasSelectionChanged was now true. Given that it's now being set synchronously, that's no longer true and is never being set. Perhaps the inputValue state needs to also be initialized synchronously as well when initialValue is provided for single-select.

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.

2 participants