diff --git a/packages/react-ui/src/hooks/useImperativeIntl.js b/packages/react-ui/src/hooks/useImperativeIntl.js index ecec5a493..73bf686af 100644 --- a/packages/react-ui/src/hooks/useImperativeIntl.js +++ b/packages/react-ui/src/hooks/useImperativeIntl.js @@ -8,37 +8,40 @@ import { } from '../localization/localeUtils'; const cache = createIntlCache(); +const intlInstanceCache = new WeakMap(); -let lastIntlConfig; -let cachedC4rIntl; +const createIntlInstance = (intlConfig) => { + const locale = intlConfig?.locale || DEFAULT_LOCALE; + const messagesLocale = findMatchingMessagesLocale(locale, messages); + const intMessages = { + ...(messages[messagesLocale] || {}), + ...(intlConfig?.messages || {}) + }; -const getGloballyCachedIntl = (intlConfig) => { - if (!cachedC4rIntl || lastIntlConfig !== intlConfig) { - // This is very simple cache exploits fact that Intl instance is actually same for most of time - // so we can reuse those maps across several instances of same components - // note, useMemo can't do that globally and flattenMessages over _app_ and c4r is quite costly and would - // be paid for every c4r component mounted. - const locale = intlConfig?.locale || DEFAULT_LOCALE; - const messagesLocale = findMatchingMessagesLocale(locale, messages); - const intMessages = { - ...(messages[messagesLocale] || {}), - ...(intlConfig?.messages || {}) - }; + const combinedMessages = flattenMessages(intMessages); + return createIntl( + { + locale, + messages: combinedMessages + }, + cache + ); +}; - const combinedMessages = flattenMessages(intMessages); - cachedC4rIntl = createIntl( - { - locale, - messages: combinedMessages - }, - cache - ); - lastIntlConfig = intlConfig; +const getGloballyCachedIntl = (intlConfig) => { + // This is very simple cache exploits fact that Intl instance is actually same for most of time + // so we can reuse those maps across several instances of same components + // note, useMemo can't cache accross many that globally and flattenMessages over _app_ and c4r messages is quite costly + // and would be paid for every c4r component mounted. + let cachedInstance = intlInstanceCache.get(intlConfig); + if (cachedInstance) { + return cachedInstance; } - return cachedC4rIntl; + const newInstance = createIntlInstance(intlConfig); + intlInstanceCache.set(intlConfig, newInstance); + return newInstance; }; export default function useImperativeIntl(intlConfig) { - // second level cache, in components is just to avoid re-creating the Intl instance if user is rendering many languages in one app - return useMemo(() => getGloballyCachedIntl(intlConfig), [intlConfig]); + return getGloballyCachedIntl(intlConfig); }