-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Block Editor: Fix some usages of useSelect that return unstable results #46226
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
Conversation
|
Size Change: 0 B Total Size: 1.32 MB ℹ️ View Unchanged
|
Mamaduka
left a comment
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.
tyxla
left a comment
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.
Great work Jarda 🚀
| ); | ||
| }, | ||
| ( state, rootClientId ) => [ | ||
| ( state, blocks, rootClientId ) => [ |
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.
😅
| const selectedBlockPossibleTransformations = selectedBlock | ||
| ? getBlockTransformItems( [ selectedBlock ], rootClientId ) | ||
| : []; | ||
| ? getBlockTransformItems( selectedBlock, rootClientId ) |
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.
👍
…46226) * UngroupButton: return stable innerBlocks value * getBlockTransformItems: fix params for the dependants function * BlockActionsMenu: pass bare selectedBlock to getBlockTransformItems to enable memoization
When fixing unit tests for the React 18 migration, I discovered there are some unwanted component rerenders. They happen after editing rich text, when there is a debounced (after 1s) creation of an undo level and dispatch of the
MARK_LAST_CHANGE_AS_PERSISTENTaction. The only selector that changes return value after this action should ever be onlyisLastBlockChangePersistent, and theuseBlockSynchook that uses it. Nothing else.But there are a few components that rerender:
The
UngroupButtoncomponent has a select call that returns an emptyinnerBlocksarray if theisUngroupablevalue isfalse. This array is a new instance on each call, leading to rerenders. I extracted it to a module-level constant.The
BlockActionsMenucomponent does something similar withselectedBlockPossibleTransformationswhen there is no selected block. Also, it disables memoization of thegetBlockTransformItemsselection because it passes a new[ selectedBlock ]array to it on every call.rememoreturns a memoized value only if all the args are exactly the same. I fixed this by passing only the stableselectedBlockobject to the selector. The selector will normalize the value to an one-item array internally.The
getBlockTransformItemsselector also has a little bug in the dependants callback. There are wrong args. Theblocksarg was interpreted asrootClientIdand the of course thestate.blockListSettings[ rootClientId ]is invalid, always returningundefined.How to test:
Run React Native unit tests for the list block:
Before this patch, it would report "update not wrapped in
act()" warnings. Because theuseSelecthook detected changes and forced rerender of a component. After this patch, these warnings disappear.