-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
fix: Guard against a block styles crash due to null block values #56903
Conversation
Size Change: 0 B Total Size: 1.71 MB ℹ️ View Unchanged
|
Flaky tests detected in d57cf63. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/7143982446
|
function BlockStyles( { clientId, url } ) { | ||
const selector = ( select ) => { | ||
const { getBlock } = select( blockEditorStore ); | ||
const { getBlockStyles } = select( blocksStore ); | ||
const block = getBlock( clientId ); | ||
return { | ||
styles: getBlockStyles( block.name ), | ||
className: block.attributes.className || '', | ||
styles: getBlockStyles( block?.name ) || EMPTY_ARRAY, |
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.
Curious - what's the purpose of this idiom in RN over just a []
literal?
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.
JavaScript does not consider two seemingly equal array literals to be equivalent. I.e., [] === []
returns false
.
This becomes important in this particular context as the code in question is a "selector" for querying state in the store. Selectors are a React ecosystem concept that I believe originates from Redux. Selectors provide state to the UI and related logic.
When a selector's return value changes, the UI re-renders for the new value. So, it is a best practice or optimization to avoid returning unnecessary "new" values, which would trigger unnecessary updates to the UI and incur a performance cost.
The Gutenberg project has a development tool that helps avoid introducing unnecessary "new" values from selectors, which helped me ensure I addressed it appropriately. We have a few existing instances to address in the mobile editor.
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.
Thanks! So the object stays constant, and no change is detected.
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.
Makes sense to me @dcalhoun! I tested with the patch applied with and without the fix and it behaved as expected.
Good work! 🚀
In certain scenarios, e.g., when the editor hangs due to poor performance, the `getBlock` value unexpectedly returns `null`. To guard against a crash in this scenario, we now conditionally access attributes on the block. A ideal resolution would be improving editor performance to avoid the scenario where a race condition causes a crash, but the fact remains that `getBlock` _can_ return `null` values and that we should not presume that it will not.
b6da7b2
to
d57cf63
Compare
What?
Guard against
null
values returned fromgetBlock
.Why?
Fixes wordpress-mobile/gutenberg-mobile#6128. Mitigate
disruptive crashes caused by accessing attributes on a
null
value.How?
In certain scenarios, e.g., when the editor hangs due to poor
performance, the
getBlock
value unexpectedly returnsnull
. To guardagainst a crash in this scenario, we now conditionally access attributes
on the block.
A ideal resolution would be improving editor performance to avoid the
scenario where a race condition causes a crash, but the fact remains
that
getBlock
can returnnull
values and that we should notpresume that it will not.
Additional details are shared in wordpress-mobile/gutenberg-mobile#6128 (comment).
Testing Instructions
The real world scenario where this occurs is difficult to replicate
consistently, as it appears to depend upon a race condition prevalent during
hangs caused by poor app performance. Therefore, a contrived testing approach
is applying the following diff with and without the proposed changes to ensure that
the component correctly handles
null
block values.Test Diff
Testing Instructions for Keyboard
n/a
Screenshots or screencast
It is worth noting that guarding against the crash results in an unexpected block controls state where the block styles are missing. Hypothetically, the block styles would become visible once the block value is no longer
null
. This is unavoidable until the editor performance is addressed and the race condition is avoided.