diff --git a/packages/compose/src/hooks/use-media-query/index.js b/packages/compose/src/hooks/use-media-query/index.js index 59e6e5d99a4af..598ab006ecb74 100644 --- a/packages/compose/src/hooks/use-media-query/index.js +++ b/packages/compose/src/hooks/use-media-query/index.js @@ -3,6 +3,8 @@ */ import { useMemo, useSyncExternalStore } from '@wordpress/element'; +const matchMediaCache = new Map(); + /** * A new MediaQueryList object for the media query * @@ -10,12 +12,23 @@ import { useMemo, useSyncExternalStore } from '@wordpress/element'; * @return {MediaQueryList|null} A new object for the media query */ function getMediaQueryList( query ) { + if ( ! query ) { + return null; + } + + let match = matchMediaCache.get( query ); + + if ( match ) { + return match; + } + if ( - query && typeof window !== 'undefined' && typeof window.matchMedia === 'function' ) { - return window.matchMedia( query ); + match = window.matchMedia( query ); + matchMediaCache.set( query, match ); + return match; } return null; diff --git a/packages/compose/src/hooks/use-media-query/test/index.js b/packages/compose/src/hooks/use-media-query/test/index.js index 88b2c1b0a3bd2..f8a61a8469c07 100644 --- a/packages/compose/src/hooks/use-media-query/test/index.js +++ b/packages/compose/src/hooks/use-media-query/test/index.js @@ -2,7 +2,7 @@ * External dependencies */ import { act, render } from '@testing-library/react'; -import { matchMedia, setMedia, cleanup } from 'mock-match-media'; +import { matchMedia, setMedia } from 'mock-match-media'; /** * Internal dependencies @@ -26,10 +26,11 @@ describe( 'useMediaQuery', () => { } ); afterEach( () => { - cleanup(); + // Do not clean up, this will break our cache. Browsers also do not + // reset media queries. } ); - it( 'should return true when query matches', async () => { + it( 'should return true when the query matches', async () => { const { container } = render( ); @@ -53,7 +54,7 @@ describe( 'useMediaQuery', () => { expect( container ).toHaveTextContent( 'useMediaQuery: false' ); } ); - it( 'should return false when the query does not matches', async () => { + it( 'should return false when the query does not match', async () => { const { container } = render( );