diff --git a/packages/vkui/src/components/AppRoot/ScrollContext.test.tsx b/packages/vkui/src/components/AppRoot/ScrollContext.test.tsx index 9370472b90..1aa736d645 100644 --- a/packages/vkui/src/components/AppRoot/ScrollContext.test.tsx +++ b/packages/vkui/src/components/AppRoot/ScrollContext.test.tsx @@ -46,6 +46,10 @@ describe(useScrollLock, () => { ), }); + + h.rerender(false); + h.rerender(); + expect(beforeScrollLockFn).toHaveBeenCalled(); expect(getStyleAttributeObject(document.body)).toEqual({ @@ -71,6 +75,32 @@ describe(useScrollLock, () => { clearWindowMeasuresMock(); }); + test('unmount check', () => { + const h = renderHook(useScrollLock, { + wrapper: ({ children }) => ( + ()}> + {children} + + ), + }); + + expect(getStyleAttributeObject(document.body)).toEqual({ + 'position': 'fixed', + 'top': `-${0}px`, + 'left': `-${0}px`, + 'right': '0px', + 'overflow-x': 'scroll', + 'overflow-y': 'scroll', + }); + expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.body)).toBe('none'); + expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.documentElement)).toBe('none'); // prettier-ignore + + h.unmount(); + expect(getStyleAttributeObject(document.body)).toEqual({}); + expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.body)).toBe(''); + expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.documentElement)).toBe(''); + }); + test('context api', () => { const contextRef = createRef(); render( @@ -110,13 +140,19 @@ describe(useScrollLock, () => { const beforeScrollLockFn = jest.fn(); const h = renderHook(useScrollLock, { - wrapper: ({ children }) => ( - - {children} - - - ), + wrapper: ({ children }) => { + return ( + + {children} + + + ); + }, }); + + h.rerender(false); + h.rerender(); + expect(beforeScrollLockFn).toHaveBeenCalled(); expect(getStyleAttributeObject(elRef.current)).toEqual({ diff --git a/packages/vkui/src/components/AppRoot/ScrollContext.tsx b/packages/vkui/src/components/AppRoot/ScrollContext.tsx index 6aa3b82d1f..19a89926c0 100644 --- a/packages/vkui/src/components/AppRoot/ScrollContext.tsx +++ b/packages/vkui/src/components/AppRoot/ScrollContext.tsx @@ -3,7 +3,6 @@ import * as React from 'react'; import { noop } from '@vkontakte/vkjs'; import { clamp } from '../../helpers/math'; -import { useCounter } from '../../hooks/useCounter'; import { useDOM } from '../../lib/dom'; import type { HasChildren } from '../../types'; @@ -61,29 +60,27 @@ export const useScroll = (): ScrollContextInterface => React.useContext(ScrollCo * Если счетчик больше нуля, требуется заблокировать прокрутку */ function useScrollLockController(enableScrollLock: () => void, disableScrollLock: () => void) { - const isFirstEffect = React.useRef(true); - const [count, { increment: incrementScrollLockCounter, decrement: decrementScrollLockCounter }] = - useCounter(0); + const countRef = React.useRef(0); - const needLockScroll = count > 0; - - React.useEffect(() => { - if (isFirstEffect.current) { - isFirstEffect.current = false; - return; - } - - if (needLockScroll) { + const updateScrollLock = React.useCallback(() => { + if (countRef.current > 0) { enableScrollLock(); } else { disableScrollLock(); } - }, [needLockScroll, enableScrollLock, disableScrollLock]); + }, [enableScrollLock, disableScrollLock]); + + const incrementScrollLockCounter = React.useCallback(() => { + countRef.current += 1; + updateScrollLock(); + }, [updateScrollLock]); + + const decrementScrollLockCounter = React.useCallback(() => { + countRef.current -= 1; + updateScrollLock(); + }, [updateScrollLock]); - return { - incrementScrollLockCounter, - decrementScrollLockCounter, - }; + return [incrementScrollLockCounter, decrementScrollLockCounter]; } export interface ScrollControllerProps extends HasChildren { @@ -145,7 +142,7 @@ export const GlobalScrollController = ({ children }: ScrollControllerProps): Rea window!.scrollTo(-parseInt(scrollX || '0'), -parseInt(scrollY || '0')); }, [document, window]); - const { incrementScrollLockCounter, decrementScrollLockCounter } = useScrollLockController( + const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController( enableScrollLock, disableScrollLock, ); @@ -226,7 +223,7 @@ export const ElementScrollController = ({ el.scrollTo(-parseInt(scrollX || '0'), -parseInt(scrollY || '0')); }, [elRef]); - const { incrementScrollLockCounter, decrementScrollLockCounter } = useScrollLockController( + const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController( enableScrollLock, disableScrollLock, );