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

useBlockElement: return null until ref callback has time to clean up the old element #63565

Merged
merged 1 commit into from
Jul 16, 2024

Conversation

jsnajdr
Copy link
Member

@jsnajdr jsnajdr commented Jul 15, 2024

Fixes #63448. When useBlockElement is used by a newly mounted component, return null until an effect sets the current value from the store. That avoids using a stale element value.

How to test:
Go through the reproduction steps in #63448 (comment) and verify that the bug is indeed fixed. No more crashes when switching from Tablet back to Desktop view.

@jsnajdr jsnajdr added [Type] Bug An existing feature does not function as intended Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta labels Jul 15, 2024
@jsnajdr jsnajdr requested a review from talldan July 15, 2024 13:19
@jsnajdr jsnajdr self-assigned this Jul 15, 2024
@jsnajdr jsnajdr requested a review from ellatrix as a code owner July 15, 2024 13:19
Copy link

github-actions bot commented Jul 15, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @sergiu-radu.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: sergiu-radu.

Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link

Size Change: +20 B (0%)

Total Size: 1.75 MB

Filename Size Change
build/block-editor/index.min.js 254 kB +20 B (+0.01%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 951 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.31 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.29 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/content-rtl.css 4.58 kB
build/block-editor/content.css 4.58 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
build/block-editor/style-rtl.css 16.3 kB
build/block-editor/style.css 16.3 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 310 B
build/block-library/blocks/button/editor.css 310 B
build/block-library/blocks/button/style-rtl.css 538 B
build/block-library/blocks/button/style.css 538 B
build/block-library/blocks/buttons/editor-rtl.css 336 B
build/block-library/blocks/buttons/editor.css 336 B
build/block-library/blocks/buttons/style-rtl.css 328 B
build/block-library/blocks/buttons/style.css 328 B
build/block-library/blocks/calendar/style-rtl.css 240 B
build/block-library/blocks/calendar/style.css 240 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-content/style-rtl.css 90 B
build/block-library/blocks/comment-content/style.css 90 B
build/block-library/blocks/comment-template/style-rtl.css 200 B
build/block-library/blocks/comment-template/style.css 199 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 221 B
build/block-library/blocks/comments-pagination/editor.css 211 B
build/block-library/blocks/comments-pagination/style-rtl.css 234 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 832 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 631 B
build/block-library/blocks/cover/editor-rtl.css 668 B
build/block-library/blocks/cover/editor.css 669 B
build/block-library/blocks/cover/style-rtl.css 1.62 kB
build/block-library/blocks/cover/style.css 1.6 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 314 B
build/block-library/blocks/embed/editor.css 314 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/file/view.min.js 324 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 342 B
build/block-library/blocks/form-input/style.css 342 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 470 B
build/block-library/blocks/freeform/editor-rtl.css 2.6 kB
build/block-library/blocks/freeform/editor.css 2.6 kB
build/block-library/blocks/gallery/editor-rtl.css 958 B
build/block-library/blocks/gallery/editor.css 962 B
build/block-library/blocks/gallery/style-rtl.css 1.71 kB
build/block-library/blocks/gallery/style.css 1.71 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 402 B
build/block-library/blocks/group/editor.css 402 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 346 B
build/block-library/blocks/html/editor.css 347 B
build/block-library/blocks/image/editor-rtl.css 845 B
build/block-library/blocks/image/editor.css 843 B
build/block-library/blocks/image/style-rtl.css 1.54 kB
build/block-library/blocks/image/style.css 1.54 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/image/view.min.js 1.58 kB
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 204 B
build/block-library/blocks/latest-posts/editor.css 204 B
build/block-library/blocks/latest-posts/style-rtl.css 509 B
build/block-library/blocks/latest-posts/style.css 510 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/media-text/editor-rtl.css 304 B
build/block-library/blocks/media-text/editor.css 303 B
build/block-library/blocks/media-text/style-rtl.css 516 B
build/block-library/blocks/media-text/style.css 515 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/editor-rtl.css 663 B
build/block-library/blocks/navigation-link/editor.css 664 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/editor-rtl.css 2.2 kB
build/block-library/blocks/navigation/editor.css 2.21 kB
build/block-library/blocks/navigation/style-rtl.css 2.26 kB
build/block-library/blocks/navigation/style.css 2.25 kB
build/block-library/blocks/navigation/view.min.js 1.03 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 236 B
build/block-library/blocks/paragraph/editor.css 236 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 522 B
build/block-library/blocks/post-comments-form/style.css 522 B
build/block-library/blocks/post-content/editor-rtl.css 74 B
build/block-library/blocks/post-content/editor.css 74 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 729 B
build/block-library/blocks/post-featured-image/editor.css 726 B
build/block-library/blocks/post-featured-image/style-rtl.css 341 B
build/block-library/blocks/post-featured-image/style.css 341 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 399 B
build/block-library/blocks/post-template/style.css 398 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 134 B
build/block-library/blocks/pullquote/editor.css 134 B
build/block-library/blocks/pullquote/style-rtl.css 342 B
build/block-library/blocks/pullquote/style.css 342 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 220 B
build/block-library/blocks/query-pagination/editor.css 208 B
build/block-library/blocks/query-pagination/style-rtl.css 287 B
build/block-library/blocks/query-pagination/style.css 283 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 514 B
build/block-library/blocks/query/editor.css 513 B
build/block-library/blocks/query/view.min.js 958 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 221 B
build/block-library/blocks/quote/theme.css 225 B
build/block-library/blocks/read-more/style-rtl.css 138 B
build/block-library/blocks/read-more/style.css 138 B
build/block-library/blocks/rss/editor-rtl.css 101 B
build/block-library/blocks/rss/editor.css 101 B
build/block-library/blocks/rss/style-rtl.css 288 B
build/block-library/blocks/rss/style.css 287 B
build/block-library/blocks/search/editor-rtl.css 183 B
build/block-library/blocks/search/editor.css 183 B
build/block-library/blocks/search/style-rtl.css 672 B
build/block-library/blocks/search/style.css 671 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/search/view.min.js 475 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 806 B
build/block-library/blocks/site-logo/editor.css 803 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-title/editor-rtl.css 123 B
build/block-library/blocks/site-title/editor.css 123 B
build/block-library/blocks/site-title/style-rtl.css 71 B
build/block-library/blocks/site-title/style.css 71 B
build/block-library/blocks/social-link/editor-rtl.css 338 B
build/block-library/blocks/social-link/editor.css 338 B
build/block-library/blocks/social-links/editor-rtl.css 676 B
build/block-library/blocks/social-links/editor.css 675 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.5 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/style-rtl.css 266 B
build/block-library/blocks/tag-cloud/style.css 265 B
build/block-library/blocks/template-part/editor-rtl.css 393 B
build/block-library/blocks/template-part/editor.css 393 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 108 B
build/block-library/blocks/term-description/style.css 108 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 553 B
build/block-library/blocks/video/editor.css 554 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.1 kB
build/block-library/common.css 1.1 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.9 kB
build/block-library/editor.css 11.9 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 216 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 14.6 kB
build/block-library/style.css 14.6 kB
build/block-library/theme-rtl.css 702 B
build/block-library/theme.css 707 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 52.3 kB
build/commands/index.min.js 16.1 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/components/index.min.js 221 kB
build/components/style-rtl.css 12 kB
build/components/style.css 12 kB
build/compose/index.min.js 12.9 kB
build/core-commands/index.min.js 2.78 kB
build/core-data/index.min.js 72.7 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.35 kB
build/customize-widgets/style.css 1.35 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.98 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.65 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/index.min.js 12.6 kB
build/edit-post/style-rtl.css 2.34 kB
build/edit-post/style.css 2.33 kB
build/edit-site/index.min.js 211 kB
build/edit-site/posts-rtl.css 6.64 kB
build/edit-site/posts.css 6.64 kB
build/edit-site/style-rtl.css 11.7 kB
build/edit-site/style.css 11.7 kB
build/edit-widgets/index.min.js 17.6 kB
build/edit-widgets/style-rtl.css 4.18 kB
build/edit-widgets/style.css 4.18 kB
build/editor/index.min.js 98 kB
build/editor/style-rtl.css 9.08 kB
build/editor/style.css 9.08 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.07 kB
build/format-library/style-rtl.css 506 B
build/format-library/style.css 505 B
build/hooks/index.min.js 1.54 kB
build/html-entities/index.min.js 445 B
build/i18n/index.min.js 3.58 kB
build/interactivity/debug.min.js 16.5 kB
build/interactivity/file.min.js 447 B
build/interactivity/image.min.js 1.72 kB
build/interactivity/index.min.js 13.4 kB
build/interactivity/navigation.min.js 1.16 kB
build/interactivity/query.min.js 742 B
build/interactivity/router.min.js 2.8 kB
build/interactivity/search.min.js 615 B
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.16 kB
build/list-reusable-blocks/style-rtl.css 846 B
build/list-reusable-blocks/style.css 846 B
build/media-utils/index.min.js 2.92 kB
build/modules/importmap-polyfill.min.js 12.3 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.58 kB
build/nux/style-rtl.css 749 B
build/nux/style.css 745 B
build/patterns/index.min.js 7.36 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.81 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 578 B
build/preferences/style.css 578 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 1.01 kB
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.74 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.1 kB
build/router/index.min.js 1.96 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.01 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.85 kB
build/vendors/react-dom.min.js 42.8 kB
build/vendors/react-jsx-runtime.min.js 560 B
build/vendors/react.min.js 2.65 kB
build/viewport/index.min.js 965 B
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.19 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@jsnajdr jsnajdr requested a review from ciampo July 15, 2024 14:13
@ellatrix ellatrix added Backport to WP Minor Release Pull request that needs to be backported to a WordPress minor release and removed Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta labels Jul 15, 2024
@ellatrix
Copy link
Member

I changed the labels because to be explicit here: ship has sailed for 6.6, this can only be include in the next minor release.

Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

I can confirm that this fixes the bug.

I don't fully understand why the change is required, from what I can tell, the implementation of useBlockElement in trunk doesn't seem to ever return a detached element.

It'd be great to understand this better. 😄

@jsnajdr
Copy link
Member Author

jsnajdr commented Jul 16, 2024

It'd be great to understand this better.

When a block renders, it registers its top DOM element inside a clientId->element map in the BlockRefsProvider. The useBlockRefProvider( clientId ) call inside useBlockProps does this. It does by passing a ref callback to the block's top element and adding the element to the map in the callback.

Anyone can then retrieve the block's element with useBlockElement( clientId ). This is used by various popovers and overlays, like GridVisualizer. useBlockElement reads the value from the map and immediately returns it.

When switching from iframe to non-iframe view, a block is unmounted and immediately remounted, at another DOM location with a new top element. Before it was rendered like:

<div className="editor-canvas">
  <iframe>
    <Block clientId={ clientId } />
  </iframe>
</div>

and now it's rendered like:

<div className="editor-canvas">
  <Block clientId={ clientId } />
</div>

Now we are getting to the caveat 🙂 When doing the second render, without iframe, this is the order of events:

  1. The block's render function is called. It reads the element, but useBlockElement returns the old element in the iframe. The new element doesn't even exist yet.
  2. React compares the markup returned by the render function with what is rendered and figures out it needs to destroy the iframe and create a new DOM structure.
  3. Before React destroys the iframe, it calls the ref callback with null. Only at this time the old element is unregistered from the map. But alas, the rendered markup already has a reference to it.
  4. Now React does all the DOM changes. Destroy old elements, create new ones.
  5. React calls the ref callback with the newly created element. It's registered in the map, the map calls all listeners, and a setState is scheduled for the block component that called useBlockElement. But it will read the new element only on the next render.
  6. Effect cleanup functions for the old components are called, effects for the new components are called.
  7. One of things that floating-ui's useFloating hook does on mount (in an effect) is to call whileElementsMounted. But the referenceEl it's called with is still the old element in the iframe.

My solution is that on initial render, useBlockElement always returns null. Only in an effect, after all the ref callbacks have been called and the new DOM is settled down, is useBlockElement to read the current value from the map.

It's very similar to what you do when you want to use component's own element to render it:

function Block() {
  const [ el, setEl ] = useState( null );
  return <>
    <div ref={ setEl }>Hello</div>
    <Tooltip anchorEl={ el }>World</Tooltip>
  </>
}

On initial render, el is always null, it cannot be anything else, because the element doesn't exist yet. The tooltip is initially rendered without anchorEl. Only after the ref callback is called, a second render is performed (triggered by setEl), this time with the mounted element.

Why does the bug happen only with GridVisualizer, and not with a BlockToolbar, for example? Because GridVisualizer is rendered inside the iframe, and after switching to non-iframe it's destroyed and created again. There is a mount effect, and the offending whileElementsMounted is called.

On the other hand, the block toolbar is rendered outside the iframe, in a slot. It's not destroyed and created, but merely rerendered with new props. The useBlockElement update is delayed, but whileElementsMounted is not called during that delay.

Copy link
Contributor

@ciampo ciampo left a comment

Choose a reason for hiding this comment

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

🚀 LGTM

Thank you @jsnajdr for debugging, fixing, and explaining in detail the root cause of the bug.

@jsnajdr jsnajdr merged commit f7b4229 into trunk Jul 16, 2024
75 checks passed
@jsnajdr jsnajdr deleted the fix/use-block-element-stale-element branch July 16, 2024 16:17
@github-actions github-actions bot added this to the Gutenberg 18.9 milestone Jul 16, 2024
useLayoutEffect( () => {
setBlockElement( refsMap.get( clientId ) );
return refsMap.subscribe( clientId, () =>
setBlockElement( refsMap.get( clientId ) )
Copy link
Member

Choose a reason for hiding this comment

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

On unmount, shouldn't it be set to null?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was considering this, but I think it's not needed, it wouldn't have any effect. On unmount, the component is going away, and updating its local state is not needed, because nobody is going to read it.

But maybe we can add it for consistency sake. So that the behavior is indistinguishable from the classic "store ref as state" pattern:

const [ el, setEl ] = useState( null );
return <div ref={ setEl } />;

In this case the setEl will be called with null on unmount.

useBlockRefs is basically the same pattern, store an element ref into state, but the ref and the state are in different components, and the store in the provider serves as a teleportation machine between them.

Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't it be possible to for a block to disappear, while another component is using useBlockElement, which would then still point to an unmounted DOM node?

Copy link
Member Author

Choose a reason for hiding this comment

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

Before the block disappears, the ref callback is called and sets the ref to null. Then the observable map calls its listeners and inside the useBlockElement hook, the setBlockElement inside the listener is called, and sets the local state to null. Therefore, all the references to the unmounted DOM node are cleared.

Copy link
Member Author

Choose a reason for hiding this comment

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

This issue makes me thinking that our current API for reading the elements is not very good. Ideally it should work exactly like element refs. Like this:

const blockElRef = useRef(); // can also be a ref callback
useBlockElementRef( clientId, blockElRef );

The blockElRef would be set and unset in real time as the target element changes. The point is that it is identical to how refs to local elements work:

const blockElRef = useRef(); // can also be a ref callback
return <div ref={ blockElRef } />;

Exactly the same thing, only in one case the element is local and in the other it's teleported from another location.

This is much better than the current useBlockRef hook that returns a ref with a synthetic ref.current getter.

The useBlockElementRef primitive can be used to very easily implement useBlockElement that returns the element and triggers a rerender on change:

function useBlockElement( clientId ) {
  const [ el, setEl ] = useState( null );
  useBlockElementRef( clientId, setEl );
  return el;
}

This implementation also never has the bug with returning stale unmounted elements.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, sorry, I misread this as a change to the hook inside the block rather than a change to the hook in the consumer.

Yes, that alternative seems good to me. We should try it :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Implemented in #63799 🙂

@ellatrix ellatrix added the Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Jul 18, 2024
gutenbergplugin pushed a commit that referenced this pull request Jul 18, 2024
…the old element (#63565)

Unlinked contributors: sergiu-radu.

Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
@github-actions github-actions bot added Backported to WP Core Pull request that has been successfully merged into WP Core and removed Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta labels Jul 18, 2024
Copy link

I just cherry-picked this PR to the wp/6.6 branch to get it included in the next release: e207359

@ellatrix ellatrix removed the Backport to WP Minor Release Pull request that needs to be backported to a WordPress minor release label Jul 18, 2024
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Jul 18, 2024
Bugfixes included:

* [WordPress/gutenberg#63637 Elements: Avoid specificity bump for top-level element-only selectors].
* [WordPress/gutenberg#63406 Navigation block: Allow themes to override block library text-decoration rule].
* [WordPress/gutenberg#63436 Fix invalid css for nested fullwidth layouts with zero padding applied].
* [WordPress/gutenberg#63397 Prevent empty void at the bottom of editor when block directory results are present].
* [WordPress/gutenberg#63291 Pattern overrides: Ensure "Reset" button always shows as last item and with border].
* [WordPress/gutenberg#63562 Global Styles: Disable "Reset styles" button when there are no changes].
* [WordPress/gutenberg#63093 Fix: Removed shuffle button when only 1 pattern is present].
* [WordPress/gutenberg#62675 fix: wp icon focus issue].
* [WordPress/gutenberg#63565 useBlockElement: return null until ref callback has time to clean up the old element].

Props ellatrix.
Fixes #61692.
See #61660, #61630, #61656.

git-svn-id: https://develop.svn.wordpress.org/trunk@58757 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Jul 18, 2024
Bugfixes included:

* [WordPress/gutenberg#63637 Elements: Avoid specificity bump for top-level element-only selectors].
* [WordPress/gutenberg#63406 Navigation block: Allow themes to override block library text-decoration rule].
* [WordPress/gutenberg#63436 Fix invalid css for nested fullwidth layouts with zero padding applied].
* [WordPress/gutenberg#63397 Prevent empty void at the bottom of editor when block directory results are present].
* [WordPress/gutenberg#63291 Pattern overrides: Ensure "Reset" button always shows as last item and with border].
* [WordPress/gutenberg#63562 Global Styles: Disable "Reset styles" button when there are no changes].
* [WordPress/gutenberg#63093 Fix: Removed shuffle button when only 1 pattern is present].
* [WordPress/gutenberg#62675 fix: wp icon focus issue].
* [WordPress/gutenberg#63565 useBlockElement: return null until ref callback has time to clean up the old element].

Props ellatrix.
Fixes #61692.
See #61660, #61630, #61656.
Built from https://develop.svn.wordpress.org/trunk@58757


git-svn-id: http://core.svn.wordpress.org/trunk@58159 1a063a9b-81f0-0310-95a4-ce76da25c4cd
github-actions bot pushed a commit to gilzow/wordpress-performance that referenced this pull request Jul 18, 2024
Bugfixes included:

* [WordPress/gutenberg#63637 Elements: Avoid specificity bump for top-level element-only selectors].
* [WordPress/gutenberg#63406 Navigation block: Allow themes to override block library text-decoration rule].
* [WordPress/gutenberg#63436 Fix invalid css for nested fullwidth layouts with zero padding applied].
* [WordPress/gutenberg#63397 Prevent empty void at the bottom of editor when block directory results are present].
* [WordPress/gutenberg#63291 Pattern overrides: Ensure "Reset" button always shows as last item and with border].
* [WordPress/gutenberg#63562 Global Styles: Disable "Reset styles" button when there are no changes].
* [WordPress/gutenberg#63093 Fix: Removed shuffle button when only 1 pattern is present].
* [WordPress/gutenberg#62675 fix: wp icon focus issue].
* [WordPress/gutenberg#63565 useBlockElement: return null until ref callback has time to clean up the old element].

Props ellatrix.
Fixes #61692.
See #61660, #61630, #61656.
Built from https://develop.svn.wordpress.org/trunk@58757


git-svn-id: https://core.svn.wordpress.org/trunk@58159 1a063a9b-81f0-0310-95a4-ce76da25c4cd
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Jul 18, 2024
Bugfixes included:

* [WordPress/gutenberg#63637 Elements: Avoid specificity bump for top-level element-only selectors].
* [WordPress/gutenberg#63406 Navigation block: Allow themes to override block library text-decoration rule].
* [WordPress/gutenberg#63436 Fix invalid css for nested fullwidth layouts with zero padding applied].
* [WordPress/gutenberg#63397 Prevent empty void at the bottom of editor when block directory results are present].
* [WordPress/gutenberg#63291 Pattern overrides: Ensure "Reset" button always shows as last item and with border].
* [WordPress/gutenberg#63562 Global Styles: Disable "Reset styles" button when there are no changes].
* [WordPress/gutenberg#63093 Fix: Removed shuffle button when only 1 pattern is present].
* [WordPress/gutenberg#62675 fix: wp icon focus issue].
* [WordPress/gutenberg#63565 useBlockElement: return null until ref callback has time to clean up the old element].

Reviewed by spacedmonkey.
Merges [58757] to the 6.6 branch.

Props ellatrix.
Fixes #61692.
See #61660, #61630, #61656.

git-svn-id: https://develop.svn.wordpress.org/branches/6.6@58760 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Jul 18, 2024
Bugfixes included:

* [WordPress/gutenberg#63637 Elements: Avoid specificity bump for top-level element-only selectors].
* [WordPress/gutenberg#63406 Navigation block: Allow themes to override block library text-decoration rule].
* [WordPress/gutenberg#63436 Fix invalid css for nested fullwidth layouts with zero padding applied].
* [WordPress/gutenberg#63397 Prevent empty void at the bottom of editor when block directory results are present].
* [WordPress/gutenberg#63291 Pattern overrides: Ensure "Reset" button always shows as last item and with border].
* [WordPress/gutenberg#63562 Global Styles: Disable "Reset styles" button when there are no changes].
* [WordPress/gutenberg#63093 Fix: Removed shuffle button when only 1 pattern is present].
* [WordPress/gutenberg#62675 fix: wp icon focus issue].
* [WordPress/gutenberg#63565 useBlockElement: return null until ref callback has time to clean up the old element].

Reviewed by spacedmonkey.
Merges [58757] to the 6.6 branch.

Props ellatrix.
Fixes #61692.
See #61660, #61630, #61656.
Built from https://develop.svn.wordpress.org/branches/6.6@58760


git-svn-id: http://core.svn.wordpress.org/branches/6.6@58162 1a063a9b-81f0-0310-95a4-ce76da25c4cd
carstingaxion pushed a commit to carstingaxion/gutenberg that referenced this pull request Jul 18, 2024
…the old element (WordPress#63565)

Unlinked contributors: sergiu-radu.

Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backported to WP Core Pull request that has been successfully merged into WP Core [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WordPress 6.6 RC3 and Query Loop block issue (When WooCommerce is active)
4 participants