diff --git a/packages/base/src/hooks/useIsRTL.ts b/packages/base/src/hooks/useIsRTL.ts index 29610866c71..e44f60c0630 100644 --- a/packages/base/src/hooks/useIsRTL.ts +++ b/packages/base/src/hooks/useIsRTL.ts @@ -1,6 +1,6 @@ import { getRTL } from '@ui5/webcomponents-base/dist/config/RTL'; import { useIsomorphicLayoutEffect } from '@ui5/webcomponents-react-base/dist/hooks'; -import { RefObject, useState } from 'react'; +import { RefObject, useRef, useState } from 'react'; const GLOBAL_DIR_CSS_VAR = '--_ui5_dir'; @@ -32,13 +32,17 @@ const detectRTL = (elementRef: RefObject) => { const useIsRTL = (elementRef: RefObject): boolean => { const [isRTL, setRTL] = useState(getRTL()); // use config RTL as best guess + const isMounted = useRef(false); useIsomorphicLayoutEffect(() => { + isMounted.current = true; setRTL(detectRTL(elementRef)); // update immediately while rendering const targets = [document.documentElement, document.body, elementRef.current].filter(Boolean); const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.attributeName === 'dir') { - setRTL(detectRTL(elementRef)); + if (isMounted.current) { + setRTL(detectRTL(elementRef)); + } } }); }); @@ -48,9 +52,10 @@ const useIsRTL = (elementRef: RefObject): boolean => { }); return () => { + isMounted.current = false; observer.disconnect(); }; - }, []); + }, [isMounted]); return isRTL; }; diff --git a/packages/main/src/components/DynamicPageTitle/index.tsx b/packages/main/src/components/DynamicPageTitle/index.tsx index 0ae500721c6..10518b31b2f 100644 --- a/packages/main/src/components/DynamicPageTitle/index.tsx +++ b/packages/main/src/components/DynamicPageTitle/index.tsx @@ -22,6 +22,7 @@ import React, { Ref, useCallback, useEffect, + useRef, useState } from 'react'; import { createUseStyles } from 'react-jss'; @@ -106,6 +107,14 @@ const DynamicPageTitle: FC = forwardRef((props: InternalP const dynamicPageTitleRef = useConsolidatedRef(ref); const [showNavigationInTopArea, setShowNavigationInTopArea] = useState(undefined); const isRtl = useIsRTL(dynamicPageTitleRef); + const isMounted = useRef(false); + + useEffect(() => { + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }, [isMounted]); if (isIE()) { containerClasses.put(classes.iEClass); @@ -134,9 +143,9 @@ const DynamicPageTitle: FC = forwardRef((props: InternalP : titleContainer.borderBoxSize; // Safari doesn't implement `borderBoxSize` const titleContainerWidth = borderBoxSize?.inlineSize ?? titleContainer.target.getBoundingClientRect().width; - if (titleContainerWidth < 1280 && !showNavigationInTopArea === false) { + if (titleContainerWidth < 1280 && !showNavigationInTopArea === false && isMounted.current) { setShowNavigationInTopArea(false); - } else if (titleContainerWidth >= 1280 && !showNavigationInTopArea === true) { + } else if (titleContainerWidth >= 1280 && !showNavigationInTopArea === true && isMounted.current) { setShowNavigationInTopArea(true); } }, 300) @@ -147,7 +156,7 @@ const DynamicPageTitle: FC = forwardRef((props: InternalP return () => { observer.disconnect(); }; - }, [dynamicPageTitleRef.current, showNavigationInTopArea]); + }, [dynamicPageTitleRef.current, showNavigationInTopArea, isMounted]); const paddingLeftRtl = isRtl ? 'paddingRight' : 'paddingLeft'; diff --git a/packages/main/src/internal/useResponsiveContentPadding.ts b/packages/main/src/internal/useResponsiveContentPadding.ts index e882f12d0f4..61bbc49f1da 100644 --- a/packages/main/src/internal/useResponsiveContentPadding.ts +++ b/packages/main/src/internal/useResponsiveContentPadding.ts @@ -15,24 +15,29 @@ const useStyles = createUseStyles( export const useResponsiveContentPadding = (element) => { const [currentRange, setCurrentRange] = useState(getCurrentRange().name); const resizeTimeout = useRef(null); + const isMounted = useRef(false); const classes = useStyles(); useEffect(() => { + isMounted.current = true; const observer = new ResizeObserver(([el]) => { if (resizeTimeout.current) { clearTimeout(resizeTimeout.current); } resizeTimeout.current = setTimeout(() => { - setCurrentRange(() => getCurrentRange(el.contentRect.width)?.name); + if (isMounted.current) { + setCurrentRange(() => getCurrentRange(el.contentRect.width)?.name); + } }, 150); }); if (element) { observer.observe(element); } return () => { + isMounted.current = false; observer.disconnect(); }; - }, [element]); + }, [element, isMounted]); return classes[currentRange]; };