From 2c95aec8f4338a1d8cdf145bb9ceee31c18b16e6 Mon Sep 17 00:00:00 2001 From: Cee Chen Date: Wed, 14 Feb 2024 09:17:31 -0800 Subject: [PATCH] Add a basic catch and warning for anonymous/non-static functions creating map entries every rerender --- src/services/theme/style_memoization.test.tsx | 14 +++++++++++++- src/services/theme/style_memoization.tsx | 5 +++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/services/theme/style_memoization.test.tsx b/src/services/theme/style_memoization.test.tsx index 6f6bd8effba..1d6b9751627 100644 --- a/src/services/theme/style_memoization.test.tsx +++ b/src/services/theme/style_memoization.test.tsx @@ -9,7 +9,8 @@ import React, { useState } from 'react'; import { css } from '@emotion/react'; import { fireEvent } from '@testing-library/react'; -import { render } from '../../test/rtl'; +import { render, renderHook } from '../../test/rtl'; +import { testOnReactVersion } from '../../test/internal'; import type { UseEuiTheme } from './hooks'; import { EuiThemeProvider } from './provider'; @@ -70,4 +71,15 @@ describe('useEuiMemoizedStyles', () => { ); expect(componentStyles).toHaveBeenCalledTimes(2); }); + + testOnReactVersion(['18'])( + 'throws an error if passed anonymous functions', + () => { + expect(() => + renderHook(() => useEuiMemoizedStyles(() => ({}))) + ).toThrowError( + 'Styles are memoized per function. Your style functions must be statically defined in order to not create a new map entry every rerender.' + ); + } + ); }); diff --git a/src/services/theme/style_memoization.tsx b/src/services/theme/style_memoization.tsx index a06a9b07bf6..d55998e3c45 100644 --- a/src/services/theme/style_memoization.tsx +++ b/src/services/theme/style_memoization.tsx @@ -62,6 +62,11 @@ export const useEuiMemoizedStyles = < const euiThemeContext = useEuiTheme(); const memoizedComponentStyles = useMemo(() => { + if (!styleGenerator.name) { + throw new Error( + 'Styles are memoized per function. Your style functions must be statically defined in order to not create a new map entry every rerender.' + ); + } const existingStyles = memoizedStyles.get(styleGenerator); if (existingStyles) { return existingStyles;