Skip to content

Commit

Permalink
Fix pattern block recursion handling (#60452)
Browse files Browse the repository at this point in the history
- Trigger recursion short circuit as early as possible before any other effects
that can reason about inner blocks have run.
- Use separate wrapper components to do this to satisfy the rule of hooks.

Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
  • Loading branch information
4 people authored Apr 4, 2024
1 parent 65fe235 commit 250c5b1
Showing 1 changed file with 32 additions and 12 deletions.
44 changes: 32 additions & 12 deletions packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,43 @@ function setBlockEditMode( setEditMode, blocks, mode ) {
} );
}

export default function ReusableBlockEdit( {
function RecursionWarning() {
const blockProps = useBlockProps();
return (
<div { ...blockProps }>
<Warning>
{ __( 'Block cannot be rendered inside itself.' ) }
</Warning>
</div>
);
}

// Wrap the main Edit function for the pattern block with a recursion wrapper
// that allows short-circuiting rendering as early as possible, before any
// of the other effects in the block edit have run.
export default function ReusableBlockEditRecursionWrapper( props ) {
const { ref } = props.attributes;
const hasAlreadyRendered = useHasRecursion( ref );

if ( hasAlreadyRendered ) {
return <RecursionWarning />;
}

return (
<RecursionProvider uniqueId={ ref }>
<ReusableBlockEdit { ...props } />
</RecursionProvider>
);
}

function ReusableBlockEdit( {
name,
attributes: { ref, content },
__unstableParentLayout: parentLayout,
clientId: patternClientId,
setAttributes,
} ) {
const registry = useRegistry();
const hasAlreadyRendered = useHasRecursion( ref );
const { record, editedRecord, hasResolved } = useEntityRecord(
'postType',
'wp_block',
Expand Down Expand Up @@ -422,14 +450,6 @@ export default function ReusableBlockEdit( {

let children = null;

if ( hasAlreadyRendered ) {
children = (
<Warning>
{ __( 'Block cannot be rendered inside itself.' ) }
</Warning>
);
}

if ( isMissing ) {
children = (
<Warning>
Expand All @@ -447,7 +467,7 @@ export default function ReusableBlockEdit( {
}

return (
<RecursionProvider uniqueId={ ref }>
<>
{ userCanEdit && onNavigateToEntityRecord && (
<BlockControls>
<ToolbarGroup>
Expand Down Expand Up @@ -477,6 +497,6 @@ export default function ReusableBlockEdit( {
) : (
<div { ...blockProps }>{ children }</div>
) }
</RecursionProvider>
</>
);
}

0 comments on commit 250c5b1

Please sign in to comment.