diff --git a/packages/block-editor/src/components/inner-blocks/get-block-context.js b/packages/block-editor/src/components/inner-blocks/get-block-context.js index 295ef380d3808d..23399949452dc0 100644 --- a/packages/block-editor/src/components/inner-blocks/get-block-context.js +++ b/packages/block-editor/src/components/inner-blocks/get-block-context.js @@ -22,18 +22,19 @@ const BLOCK_CONTEXT_CACHE = new WeakMap(); */ export default function getBlockContext( attributes, blockType ) { if ( ! BLOCK_CONTEXT_CACHE.has( blockType ) ) { - BLOCK_CONTEXT_CACHE.set( blockType, new WeakMap() ); + BLOCK_CONTEXT_CACHE.set( blockType, new Map() ); } const blockTypeCache = BLOCK_CONTEXT_CACHE.get( blockType ); - if ( ! blockTypeCache.has( attributes ) ) { - const context = mapValues( - blockType.providesContext, - ( attributeName ) => attributes[ attributeName ] - ); + const context = mapValues( + blockType.providesContext, + ( attributeName ) => attributes[ attributeName ] + ); - blockTypeCache.set( attributes, context ); + const cacheKey = JSON.stringify( context ); + if ( ! blockTypeCache.has( cacheKey ) ) { + blockTypeCache.set( cacheKey, context ); } - return blockTypeCache.get( attributes ); + return blockTypeCache.get( cacheKey ); } diff --git a/packages/block-editor/src/components/inner-blocks/test/get-block-context.js b/packages/block-editor/src/components/inner-blocks/test/get-block-context.js new file mode 100644 index 00000000000000..915e7017a40513 --- /dev/null +++ b/packages/block-editor/src/components/inner-blocks/test/get-block-context.js @@ -0,0 +1,59 @@ +/** + * WordPress dependencies + */ +import { + getBlockType, + getBlockTypes, + registerBlockType, + unregisterBlockType, +} from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import getBlockContext from '../get-block-context'; + +describe( 'getBlockContext', () => { + beforeAll( () => { + registerBlockType( 'core/fruit-basket', { + category: 'text', + title: 'Fruit Basket', + attributes: { + id: { + type: 'number', + }, + name: { + type: 'string', + }, + }, + providesContext: { basketId: 'id' }, + } ); + } ); + afterAll( () => { + getBlockTypes().forEach( ( block ) => { + unregisterBlockType( block.name ); + } ); + } ); + + it( 'should return cached value when attributes are the same', () => { + const attributes = { id: 1, name: '' }; + const blockType = getBlockType( 'core/fruit-basket' ); + + const prevContext = getBlockContext( attributes, blockType ); + const nextContext = getBlockContext( attributes, blockType ); + + expect( prevContext ).toBe( nextContext ); + } ); + + it( 'should return cached value if attributes used in context are the same', () => { + const blockType = getBlockType( 'core/fruit-basket' ); + + const prevContext = getBlockContext( { id: 1, name: '' }, blockType ); + const nextContext = getBlockContext( + { id: 1, name: 'Apples' }, + blockType + ); + + expect( prevContext ).toBe( nextContext ); + } ); +} );