-
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: InnerBlocks allowed blocks change with different sizes. #53943
Fix: InnerBlocks allowed blocks change with different sizes. #53943
Conversation
Size Change: +16 B (0%) Total Size: 1.51 MB
ℹ️ View Unchanged
|
Flaky tests detected in 4a41ed9eb7a6bc1ff2536083331a90eb07f400ff. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6076195296
|
const _allowedBlocks = useMemo( | ||
() => allowedBlocks, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
allowedBlocks | ||
[ allowedBlocks && allowedBlocks.length, ...allowedBlocks ] |
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.
I guess there's an issue here if allowedBlocks is undefined, the spreading breaks.
This will still generate a notice mentioned here #14515 (comment), no? |
If we want to avoid that warning and still not force users to "memoize" the array themselves, we could write a |
Maybe we should leave memoization to blocks/consumers? In most cases it’s easy as defining the value outside of the component and when blocks have reactive value they could handle this themselves. We can also show best practices in docs. |
I'd agree with that it was not a performance bottleneck in the editor. this particular memoization has potentially a bit impact on loading performance and would also impact typing a little bit. |
So we remove memoization? And we make sure none of our blocks creates a new reference every time? |
I'm saying the opposite personally. Write something that uses the "previous" value of allowedBlocks unless the new value is different using shallow comparison. |
57f56be
to
4a41ed9
Compare
// Store current value in ref if it is not shallow equal to the previous value. | ||
useEffect( () => { | ||
if( ! isShallowEqual( ref.current, value ) ) { | ||
ref.current = value |
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.
The problem is that, this won't "re-render" the component, so the component is going to use the old value unless there's something else in the component that causes a "re-render".
Now, we could replace this with a state value instead of a ref value but it also has a small downside: it will render the component twice: once with the old value and once with the new value. I wonder if there's a way to avoid the two renders.
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.
Maybe we could use a state update during the render; that should avoid rendering twice. Cc @kevin940726
Ref: https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes
P.S. The isShallowEqual
import is missing from the file.
Example, needs testing
function useShallowMemo( value ) {
const [ prevValue, setPrevValue ] = useState( value );
if ( ! isShallowEqual( prevValue, value ) ) {
setPrevValue( value );
}
return prevValue;
}
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 for sharing @Mamaduka just learned about this :)
bd1d3a8
to
ac098bf
Compare
I can reproduce the e2e test failure locally, manually testing the issue now. |
packages/e2e-tests/plugins/inner-blocks-allowed-blocks/index.js
Outdated
Show resolved
Hide resolved
d465cec
to
af99870
Compare
@jorgefilipecosta, it isn't clear if your recent |
af99870
to
d0d0b1b
Compare
Sorry I was not aware you submitted a fix, it was just a rebase to then work on the fix. I already re-added your fix, thank you a lot :) |
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.
The fix works well in my tests 👍
Thank you for the feedback, reviews, fixes, and all the help @Mamaduka and @youknowriad. |
Fixes: #14515
The comparison we used for memorization did not take into account the arrays may change the size. This PR fixes the issue and updates the end-to-end test to include this case.
Testing
Verify the end-to-end tests pass.