Skip to content

Commit

Permalink
useBlockSync(): Reset inner blocks when component unmounts (#51783)
Browse files Browse the repository at this point in the history
  • Loading branch information
noisysocks committed Jun 27, 2023
1 parent 260411f commit 4ba84e3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe( 'useBlockSync hook', () => {
jest.clearAllMocks();
} );

it( 'resets the block-editor blocks when the controll value changes', async () => {
it( 'resets the block-editor blocks when the controlled value changes', async () => {
const fakeBlocks = [];
const resetBlocks = jest.spyOn( blockEditorActions, 'resetBlocks' );
const replaceInnerBlocks = jest.spyOn(
Expand All @@ -58,7 +58,7 @@ describe( 'useBlockSync hook', () => {
const onChange = jest.fn();
const onInput = jest.fn();

const { rerender } = render(
const { rerender, unmount } = render(
<TestWrapper
value={ fakeBlocks }
onChange={ onChange }
Expand Down Expand Up @@ -88,9 +88,16 @@ describe( 'useBlockSync hook', () => {
expect( onInput ).not.toHaveBeenCalled();
expect( replaceInnerBlocks ).not.toHaveBeenCalled();
expect( resetBlocks ).toHaveBeenCalledWith( testBlocks );

unmount();

expect( onChange ).not.toHaveBeenCalled();
expect( onInput ).not.toHaveBeenCalled();
expect( replaceInnerBlocks ).not.toHaveBeenCalled();
expect( resetBlocks ).toHaveBeenCalledWith( [] );
} );

it( 'replaces the inner blocks of a block when the control value changes if a clientId is passed', async () => {
it( 'replaces the inner blocks of a block when the controlled value changes if a clientId is passed', async () => {
const fakeBlocks = [];
const replaceInnerBlocks = jest.spyOn(
blockEditorActions,
Expand All @@ -100,7 +107,7 @@ describe( 'useBlockSync hook', () => {
const onChange = jest.fn();
const onInput = jest.fn();

const { rerender } = render(
const { rerender, unmount } = render(
<TestWrapper
clientId="test"
value={ fakeBlocks }
Expand Down Expand Up @@ -138,8 +145,16 @@ describe( 'useBlockSync hook', () => {
expect( onChange ).not.toHaveBeenCalled();
expect( onInput ).not.toHaveBeenCalled();
expect( resetBlocks ).not.toHaveBeenCalled();
// We can't check the args because the blocks are cloned.
expect( replaceInnerBlocks ).toHaveBeenCalled();
expect( replaceInnerBlocks ).toHaveBeenCalledWith( 'test', [
expect.objectContaining( { name: 'test/test-block' } ),
] );

unmount();

expect( onChange ).not.toHaveBeenCalled();
expect( onInput ).not.toHaveBeenCalled();
expect( resetBlocks ).not.toHaveBeenCalled();
expect( replaceInnerBlocks ).toHaveBeenCalledWith( 'test', [] );
} );

it( 'does not add the controlled blocks to the block-editor store if the store already contains them', async () => {
Expand Down
19 changes: 19 additions & 0 deletions packages/block-editor/src/components/provider/use-block-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ export default function useBlockSync( {
}
};

// Clean up the changes made by setControlledBlocks() when the component
// containing useBlockSync() unmounts.
const unsetControlledBlocks = () => {
__unstableMarkNextChangeAsNotPersistent();
if ( clientId ) {
setHasControlledInnerBlocks( clientId, false );
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks( clientId, [] );
} else {
resetBlocks( [] );
}
};

// Add a subscription to the block-editor registry to detect when changes
// have been made. This lets us inform the data source of changes. This
// is an effect so that the subscriber can run synchronously without
Expand Down Expand Up @@ -287,4 +300,10 @@ export default function useBlockSync( {
unsubscribe();
};
}, [ registry, clientId ] );

useEffect( () => {
return () => {
unsetControlledBlocks();
};
}, [] );
}

0 comments on commit 4ba84e3

Please sign in to comment.