Skip to content

Conversation

@devongovett
Copy link
Member

@devongovett devongovett commented Nov 3, 2023

Fixes #5120

This fixes ComboBox re-opening after selecting an option in the RAC docs. The problem stems from how React batches updates, and how our collection implementation works. Our collection implementation uses React's useSyncExternalStore hook to trigger updates. Inside ComboBox, we have a lastValue ref, and an inputValue state, which are updated simultaneously. Then, in the next render, we assume that lastValue.current will equal inputValue. However, this assumption is not true when some ancestor component uses useSyncExternalStore, which triggers a synchronous update. Essentially, setState is asynchronous, but a synchronous update can preempt it. In that case, the ref will already be updated but the state will not. This CodeSandbox has a minimal reproduction.

The solution is to move lastValue to state instead of a ref. There are probably a lot more instances of this pattern that we should audit throughout the codebase, but this is the first real world case where this assumption turned out to be incorrect.

This started appearing in our docs due to the change from ReactDOM.render to ReactDOM.createRoot. render behaves like React 17, so state updates run synchronously. createRoot opts-into concurrent features.

@rspbot
Copy link

rspbot commented Nov 3, 2023

Copy link
Member

@LFDanLu LFDanLu left a comment

Choose a reason for hiding this comment

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

Tested the RAC docs and storybook examples and things seem to still work, fingers crossed

@rspbot
Copy link

rspbot commented Nov 3, 2023

@rspbot
Copy link

rspbot commented Nov 3, 2023

## API Changes

unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any', access: 'private' }
unknown top level export { type: 'any', access: 'private' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'identifier', name: 'Column' }
unknown top level export { type: 'identifier', name: 'Column' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown type { type: 'link' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }
unknown top level export { type: 'any' }

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.

[RAC] ComboBox stays open after selection

5 participants