diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 97a366e8884d2f..df81bd5df22f0b 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -225,6 +225,17 @@ const withBlockCache = ( reducer ) => ( state = {}, action ) => { } newState.cache = state.cache ? state.cache : {}; + /** + * For each clientId provided, traverses up parents, adding the provided clientIds + * and each parent's clientId to the returned array. + * + * When calling this function consider that it uses the old state, so any state + * modifications made by the `reducer` will not be present. + * + * @param {Array} clientIds an Array of block clientIds. + * + * @return {Array} The provided clientIds and all of their parent clientIds. + */ const getBlocksWithParentsClientIds = ( clientIds ) => { return clientIds.reduce( ( result, clientId ) => { let current = clientId; @@ -264,11 +275,12 @@ const withBlockCache = ( reducer ) => ( state = {}, action ) => { }; break; case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': + const parentClientIds = fillKeysWithEmptyObject( getBlocksWithParentsClientIds( action.replacedClientIds ) ); + newState.cache = { ...omit( newState.cache, action.replacedClientIds ), - ...fillKeysWithEmptyObject( - getBlocksWithParentsClientIds( keys( flattenBlocks( action.blocks ) ) ), - ), + ...omit( parentClientIds, action.replacedClientIds ), + ...fillKeysWithEmptyObject( keys( flattenBlocks( action.blocks ) ) ), }; break; case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': diff --git a/packages/block-editor/src/store/test/reducer.js b/packages/block-editor/src/store/test/reducer.js index 0626f57fb41291..7eb698be778650 100644 --- a/packages/block-editor/src/store/test/reducer.js +++ b/packages/block-editor/src/store/test/reducer.js @@ -759,21 +759,29 @@ describe( 'state', () => { blocks: [ wrapperBlock ], } ); + const originalWrapperBlockCacheKey = original.cache[ wrapperBlock.clientId ]; + const state = blocks( original, { type: 'REPLACE_BLOCKS', clientIds: [ nestedBlock.clientId ], blocks: [ replacementBlock ], } ); + const newWrapperBlockCacheKey = state.cache[ wrapperBlock.clientId ]; + + expect( newWrapperBlockCacheKey ).not.toBe( originalWrapperBlockCacheKey ); + expect( state.order ).toEqual( { '': [ wrapperBlock.clientId ], [ wrapperBlock.clientId ]: [ replacementBlock.clientId ], [ replacementBlock.clientId ]: [], } ); + expect( state.parents ).toEqual( { [ wrapperBlock.clientId ]: '', [ replacementBlock.clientId ]: wrapperBlock.clientId, } ); + expect( state.cache ).toEqual( { [ wrapperBlock.clientId ]: {}, [ replacementBlock.clientId ]: {},